Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you draw a line programmatically from a view controller?

I have a UIViewController. How do I draw a line in one of its programmatically created views?

like image 906
mkc842 Avatar asked May 30 '13 21:05

mkc842


People also ask

How do I embed a view controller?

Just drag a container view out into your main view controller and use the embed segue from it to your embedded view controller. It will properly set up all the view controller hierarchy for you.


2 Answers

There are two common techniques.

  1. Using CAShapeLayer:

    • Create a UIBezierPath (replace the coordinates with whatever you want):

      UIBezierPath *path = [UIBezierPath bezierPath]; [path moveToPoint:CGPointMake(10.0, 10.0)]; [path addLineToPoint:CGPointMake(100.0, 100.0)]; 
    • Create a CAShapeLayer that uses that UIBezierPath:

      CAShapeLayer *shapeLayer = [CAShapeLayer layer]; shapeLayer.path = [path CGPath]; shapeLayer.strokeColor = [[UIColor blueColor] CGColor]; shapeLayer.lineWidth = 3.0; shapeLayer.fillColor = [[UIColor clearColor] CGColor]; 
    • Add that CAShapeLayer to your view's layer:

      [self.view.layer addSublayer:shapeLayer]; 

    In previous versions of Xcode, you had to manually add QuartzCore.framework to your project's "Link Binary with Libraries" and import the <QuartzCore/QuartzCore.h> header in your .m file, but that's not necessary anymore (if you have the "Enable Modules" and "Link Frameworks Automatically" build settings turned on).

  2. The other approach is to subclass UIView and then use CoreGraphics calls in the drawRect method:

    • Create a UIView subclass and define a drawRect that draws your line.

      You can do this with 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); } 

      Or using 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]; } 
    • Then you can either use this view class as the base class for your NIB/storyboard or view, or you can have your view controller programmatically add it as a subview:

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

The Swift renditions of the two above approaches are as follows:

  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 subclass:

    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()     }  } 

    And add it to your view hierarchy:

    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 

    Above, I'm adding PathView programmatically, but you can add it via IB, too, and just set its path programmatically.

like image 146
Rob Avatar answered Sep 18 '22 12:09

Rob


Create a UIView and add it as a subview of your view controller's view. You can modify this subview's height or width to be very small so that it looks like a line. If you need to draw a diagonal line you can modify the subviews transform property.

e.g. draw black horizontal line. This is called from within your view controller's implementation

UIView *lineView = [[UIView alloc] initWithFrame:CGRectMake(0,0, self.view.frame.size.width, 1)]; lineView.backgroundColor = [UIColor blackColor]; [self.view addSubview:lineView]; 
like image 29
Jeff Ames Avatar answered Sep 19 '22 12:09

Jeff Ames