你如何从视图控制器以编程方式绘制一条线?

我有一个UIViewController 。 我想在其中一个程序创build的视图中画一条线。 看起来很简单,但我还没有find可用的示例代码。

有两种常用的技术。

  1. 使用CAShapeLayer

    • 创build一个UIBezierPath (用你想要的任何东西replace坐标):

       UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(10.0, 10.0)]; [path addLineToPoint:CGPointMake(100.0, 100.0)]; 
    • 创build一个使用该UIBezierPath

       CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.path = [path CGPath]; shapeLayer.strokeColor = [[UIColor blueColor] CGColor]; shapeLayer.lineWidth = 3.0; shapeLayer.fillColor = [[UIColor clearColor] CGColor]; 
    • CAShapeLayer添加到视图的图层中:

       [self.view.layer addSublayer:shapeLayer]; 

    在以前的Xcode版本中,必须手动将QuartzCore.framework添加到项目的“Link Binary with Libraries”中,并在.m文件中导入<QuartzCore/QuartzCore.h>头文件,但这不再必要(如果您拥有“启用模块”和“自动链接框架”构build设置打开)。

  2. 另一种方法是UIView ,然后在drawRect方法中使用CoreGraphics调用:

    • 创build一个UIView子类并定义一个drawRect来绘制你的线条。

      你可以用Core Graphics做到这一点:

       - (void)drawRect:(CGRect)rect { CGContextRef context = UIGraphicsGetCurrentContext(); CGContextSetStrokeColorWithColor(context, [[UIColor blueColor] CGColor]); CGContextSetLineWidth(context, 3.0); CGContextMoveToPoint(context, 10.0, 10.0); CGContextAddLineToPoint(context, 100.0, 100.0); CGContextDrawPath(context, kCGPathStroke); } 

      或者使用UIKit

       - (void)drawRect:(CGRect)rect { UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(10.0, 10.0)]; [path addLineToPoint:CGPointMake(100.0, 100.0)]; path.lineWidth = 3; [[UIColor blueColor] setStroke]; [path stroke]; } 
    • 然后,您可以使用这个视图类作为您的NIB /故事板或视图的基类,或者您可以让您的视图控制器以编程方式将其添加为子视图:

       PathView *pathView = [[PathView alloc] initWithFrame:self.view.bounds]; pathView.backgroundColor = [UIColor clearColor]; [self.view addSubview: pathView]; 

上述两种方法的Swift演绎​​如下:

  1. CAShapeLayer

     // create path let path = UIBezierPath() path.move(to: CGPoint(x: 10, y: 10)) path.addLine(to: CGPoint(x: 100, y: 100)) // Create a `CAShapeLayer` that uses that `UIBezierPath`: let shapeLayer = CAShapeLayer() shapeLayer.path = path.cgPath shapeLayer.strokeColor = UIColor.blue.cgColor shapeLayer.fillColor = UIColor.clear.cgColor shapeLayer.lineWidth = 3 // Add that `CAShapeLayer` to your view's layer: view.layer.addSublayer(shapeLayer) 
  2. UIView子类:

     class PathView: UIView { var path: UIBezierPath? { didSet { setNeedsDisplay() } } var pathColor: UIColor = .blue { didSet { setNeedsDisplay() } } override func draw(_ rect: CGRect) { // stroke the path pathColor.setStroke() path?.stroke() } } 

    并将其添加到您的视图层次结构中:

     let pathView = PathView() pathView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(pathView) NSLayoutConstraint.activate([ pathView.leadingAnchor.constraint(equalTo: view.leadingAnchor), pathView.trailingAnchor.constraint(equalTo: view.trailingAnchor), pathView.topAnchor.constraint(equalTo: view.topAnchor), pathView.bottomAnchor.constraint(equalTo: view.bottomAnchor) ]) pathView.backgroundColor = .clear let path = UIBezierPath() path.move(to: CGPoint(x: 10, y: 10)) path.addLine(to: CGPoint(x: 100, y: 100)) path.lineWidth = 3 pathView.path = path 

    以上,我PathView编程的方式添加了PathView ,但是您也可以通过IB添加它,并且以编程方式设置它的path

创build一个UIView并将其添加为视图控制器视图的子视图。 您可以修改此子视图的高度或宽度,使其看起来像一条线。 如果你需要绘制一条对angular线,你可以修改子视图transform属性。

例如绘制黑色的水平线。 这是从你的视图控制器的实现中调用的

UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.frame.size.width, 1)]; lineView.backgroundColor = [UIColor blackColor]; [self.view addSubview:lineView];

下面是一个很酷的技术,你可能会发现它很有用: 在Objective-C中使用块进行绘制以避免子类化

在项目中包含文章的通用视图子类,那么这是您可以在视图控制器中创build一个视图的代码types,用于绘制一行:

 DrawView* drawableView = [[[DrawView alloc] initWithFrame:CGRectMake(0,0,320,50)] autorelease]; drawableView.drawBlock = ^(UIView* v,CGContextRef context) { CGPoint startPoint = CGPointMake(0,v.bounds.size.height-1); CGPoint endPoint = CGPointMake(v.bounds.size.width,v.bounds.size.height-1); CGContextSetStrokeColorWithColor(context, [UIColor grayColor].CGColor); CGContextSetLineWidth(context, 1); CGContextMoveToPoint(context, startPoint.x + 0.5, startPoint.y + 0.5); CGContextAddLineToPoint(context, endPoint.x + 0.5, endPoint.y + 0.5); CGContextStrokePath(context); }; [self.view addSubview:drawableView]; 

你可以使用UIImageView来画线。

但是,它允许跳过子分类。 而且,我很less倾向于Core Graphics仍然可以使用它。 你可以把它放在ViewDidLoad

  UIGraphicsBeginImageContext(self.view.frame.size); [self.myImageView.image drawInRect:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)]; CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); CGContextSetLineWidth(UIGraphicsGetCurrentContext(), brush); CGContextMoveToPoint(UIGraphicsGetCurrentContext(), 50, 50); CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), 200, 200); CGContextStrokePath(UIGraphicsGetCurrentContext()); CGContextFlush(UIGraphicsGetCurrentContext()); self.myImageView.image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); 

除了Rob的回答,第三种方法是使用UIImageView – 掩盖它 – xib的视图。 (这是xcode 5在xib上拖动时的默认UIImageView外观)

欢呼声和+1!

Swift 3:

 let path = UIBezierPath() path.move(to: CGPoint(x: 10, y: 10)) path.addLine(to: CGPoint(x: 100, y: 100)) let shapeLayer = CAShapeLayer() shapeLayer.path = path.cgPath shapeLayer.strokeColor = UIColor.blue.cgColor shapeLayer.lineWidth = 3.0 view.layer.addSublayer(shapeLayer) 

你不应该真的,但是如果由于某种原因对你有意义的话,你可以创build一个UIView的子类,例如叫做DelegateDrawView,它需要一个实现类似方法的委托

 - (void)delegateDrawView:(DelegateDrawView *)aDelegateDrawView drawRect:(NSRect)dirtyRect 

然后在方法 – [DelegateDrawView drawRect:]你调用你的委托方法。

但是你为什么要把视图代码放在控制器中。

你最好创build一个UIView的子类,在它的两个angular之间画一条线,你可以有一个属性来设置哪两个,然后将视图放在你想要的位置,从你的视图控制器。

在你的视图里面绘制很简单,@ROB先生说2个方法我拿第一个方法。

只需将代码粘贴到你想要的地方即可。

 -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { UITouch *touch = [[event allTouches] anyObject]; startingPoint = [touch locationInView:self.view]; NSLog(@"Touch starting point = x : %f Touch Starting Point = y : %f", touchPoint.x, touchPoint.y); } -(void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { } -(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { UITouch *touch = [[event allTouches] anyObject]; touchPoint = [touch locationInView:self.view]; NSLog(@"Touch end point =x : %f Touch end point =y : %f", touchPoint.x, touchPoint.y); } -(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { UITouch *touch = [[event allTouches] anyObject]; touchPoint = [touch locationInView:self.view]; UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)]; [path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)]; startingPoint=touchPoint; CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.path = [path CGPath]; shapeLayer.strokeColor = [[UIColor blueColor] CGColor]; shapeLayer.lineWidth = 3.0; shapeLayer.fillColor = [[UIColor redColor] CGColor]; [self.view.layer addSublayer:shapeLayer]; NSLog(@"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y); [self.view setNeedsDisplay]; } - (void)tapGestureRecognizer:(UIGestureRecognizer *)recognizer { CGPoint tappedPoint = [recognizer locationInView:self.view]; CGFloat xCoordinate = tappedPoint.x; CGFloat yCoordinate = tappedPoint.y; NSLog(@"Touch Using UITapGestureRecognizer x : %fy : %f", xCoordinate, yCoordinate); } 

它会画出一条线,手指移动的地方