你如何从视图控制器以编程方式绘制一条线?
我有一个UIViewController
。 我想在其中一个程序创build的视图中画一条线。 看起来很简单,但我还没有find可用的示例代码。
有两种常用的技术。
-
使用
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设置打开)。 -
-
另一种方法是
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演绎如下:
-
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)
-
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); }
它会画出一条线,手指移动的地方