在UIView中画线


86

我需要在UIView中绘制一条水平线。什么是最简单的方法。例如,我想在y-coord = 200处绘制黑色水平线。

我没有使用Interface Builder。


1
这是在所有iOS中正确拥有单像素线条并使其在情节
提要中

Answers:


122

在您的情况下(水平线),最简单的方法是添加具有黑色背景色和边框的子视图[0, 200, 320, 1]

代码示例(希望没有错误-我在没有Xcode的情况下编写了代码):

UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0, 200, self.view.bounds.size.width, 1)];
lineView.backgroundColor = [UIColor blackColor];
[self.view addSubview:lineView];
[lineView release];
// You might also keep a reference to this view 
// if you are about to change its coordinates.
// Just create a member and a property for this...

另一种方法是创建一个将在其drawRect方法中画一条线的类(您可以在此处查看我的代码示例)。


无需情节提要中的任何代码即可执行此操作。更容易,更好。
coolcool1994 '17

3
@ coolcool1994,您是否没有注意到“我没有使用Interface Builder”。问题的要求?
Michael Kessler

312

也许这有点晚了,但我想补充一点,这是一种更好的方法。使用UIView很简单,但是相对较慢。此方法将覆盖视图如何绘制自身并更快:

- (void)drawRect:(CGRect)rect {
    [super drawRect:rect];

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetStrokeColorWithColor(context, [UIColor redColor].CGColor);

    // Draw them with a 2.0 stroke width so they are a bit more visible.
    CGContextSetLineWidth(context, 2.0f);

    CGContextMoveToPoint(context, 0.0f, 0.0f); //start at this point

    CGContextAddLineToPoint(context, 20.0f, 20.0f); //draw to this point

    // and now draw the Path!
    CGContextStrokePath(context);
}

如果在UIView中使用此代码,则此示例中的坐标是相对于视图边界还是整个屏幕的坐标?
ChrisP

难道一个不需要调用CGContextBeginPath(context);之前CGContextMoveToPoint(...);
i_am_jorf 2011年

37
使用视图做到这一点并不可怕。例如,当在方向更改期间执行隐式动画时,它使事情变得容易。如果只是一个,那么另一个UIView并不会那么昂贵,并且代码要简单得多。
i_am_jorf 2012年

另外,您可以使用以下代码获取边界和中点:CGPoint midPoint; midPoint.x = self.bounds.size.width / 2; midPoint.y = self.bounds.size.height / 2;
coolcool1994

1
是的,“慢”的评论是不明智的。任何时候屏幕上都有大量的简单UIViews。请注意,绘制一个(!)文本字符以及所涉及的所有处理都会使绘制一个填充的UIView陷入沼泽。
Fattie 2014年

30

Swift 3和Swift 4

这是在视图末尾绘制灰线的方式(与b123400的答案相同)

class CustomView: UIView {

    override func draw(_ rect: CGRect) {
        super.draw(rect)
        
        if let context = UIGraphicsGetCurrentContext() {
            context.setStrokeColor(UIColor.gray.cgColor)
            context.setLineWidth(1)
            context.move(to: CGPoint(x: 0, y: bounds.height))
            context.addLine(to: CGPoint(x: bounds.width, y: bounds.height))
            context.strokePath()
        }
    }
}

从viewDidLayoutSubviews调用时,“ if let上下文”失败。
奥斯卡

14

只需添加一个不带文本和背景色的标签即可。设置您选择的坐标以及高度和宽度。您可以手动执行此操作,也可以使用Interface Builder进行操作。


11

您可以为此使用UIBezierPath类:

并可以绘制任意数量的线:

我有子类化UIView:

    @interface MyLineDrawingView()
    {
       NSMutableArray *pathArray;
       NSMutableDictionary *dict_path;
       CGPoint startPoint, endPoint;
    }

       @property (nonatomic,retain)   UIBezierPath *myPath;
    @end

并初始化将用于绘制线条的pathArray和dictPAth对象。我正在从自己的项目中编写代码的主要部分:

- (void)drawRect:(CGRect)rect
{

    for(NSDictionary *_pathDict in pathArray)
    {
        [((UIColor *)[_pathDict valueForKey:@"color"]) setStroke]; // this method will choose the color from the receiver color object (in this case this object is :strokeColor)
        [[_pathDict valueForKey:@"path"] strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];
    }

    [[dict_path objectForKey:@"color"] setStroke]; // this method will choose the color from the receiver color object (in this case this object is :strokeColor)
    [[dict_path objectForKey:@"path"] strokeWithBlendMode:kCGBlendModeNormal alpha:1.0];

}

touchesBegin方法:

UITouch *touch = [touches anyObject];
startPoint = [touch locationInView:self];
myPath=[[UIBezierPath alloc]init];
myPath.lineWidth = currentSliderValue*2;
dict_path = [[NSMutableDictionary alloc] init];

touchesMoved方法:

UITouch *touch = [touches anyObject];
endPoint = [touch locationInView:self];

 [myPath removeAllPoints];
        [dict_path removeAllObjects];// remove prev object in dict (this dict is used for current drawing, All past drawings are managed by pathArry)

    // actual drawing
    [myPath moveToPoint:startPoint];
    [myPath addLineToPoint:endPoint];

    [dict_path setValue:myPath forKey:@"path"];
    [dict_path setValue:strokeColor forKey:@"color"];

    //                NSDictionary *tempDict = [NSDictionary dictionaryWithDictionary:dict_path];
    //                [pathArray addObject:tempDict];
    //                [dict_path removeAllObjects];
    [self setNeedsDisplay];

touchesEnded方法:

        NSDictionary *tempDict = [NSDictionary dictionaryWithDictionary:dict_path];
        [pathArray addObject:tempDict];
        [dict_path removeAllObjects];
        [self setNeedsDisplay];

11

另一种(甚至更短)的可能性。如果您在drawRect内,则如下所示:

[[UIColor blackColor] setFill];
UIRectFill((CGRect){0,200,rect.size.width,1});

0

基于Guy Daher的答案。

我尽量避免使用?因为如果GetCurrentContext()返回nil,它可能导致应用程序崩溃。

我不会检查if语句:

class CustomView: UIView 
{    
    override func draw(_ rect: CGRect) 
    {
        super.draw(rect)
        if let context = UIGraphicsGetCurrentContext()
        {
            context.setStrokeColor(UIColor.gray.cgColor)
            context.setLineWidth(1)
            context.move(to: CGPoint(x: 0, y: bounds.height))
            context.addLine(to: CGPoint(x: bounds.width, y: bounds.height))
            context.strokePath()
        }
    }
}

2
如果该if子句的原因只是为了取消选择该子句,请改用一条guard语句。
朱利奥·弗洛雷斯

-1

添加不带文本且背景色与框架大小相对应的标签(例如:height = 1)。通过代码或在界面生成器中进行操作。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.