How to Draw a Line Programmatically from a View Controller

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

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 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.

draw line in place of x axis in view controller

To draw a line in the middle of the screen, just assign the Line.swift file to UIView on which you want to draw a line.

Line.swift file

class Line:UIView {

var line = UIBezierPath()

func drawLine() {
line.move(to: CGPoint(x: 0, y: bounds.height / 2))
line.addLine(to: CGPoint(x: (bounds.width) , y: bounds.height / 2))
UIColor.black.setStroke()
line.lineWidth = 0.1
line.stroke()

}

override func draw(_ rect: CGRect) {
drawLine()
}
}

To assign it to your UIView, open the main.storyboard and click on the view where you want to draw the line. Then, go into upper right tabs which would look like this

Sample Image

You can see inside the class field, there is a placeholder called "UIView". Type there Line and hit enter, and then just run the project. You 'll be able to see the line in the middle of the view. No need to declare or call any function. Just assign this class and run the project.

iOS: Programmatically drawing lines in UIView

Code to achieve the above image:

//Post this function in your TableViewController
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = HeaderTableView()
view.title.text = "THIS WEEK"

return view
}

//Custom UIView Class
class CustomView: UIView {

var shouldSetupConstraints = true
var title: UILabel!
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
let textStartX = Int((title.frame.minX))
let textEndX = Int((title.frame.maxX))
let midY = Int(self.frame.midY)
self.drawLine(startX: 8, toEndingX: textStartX - 8, startingY: midY, toEndingY: midY, ofColor: UIColor.white, widthOfLine: 1, inView: self)
self.drawLine(startX: textEndX + 8, toEndingX: Int(self.frame.maxX) - 8, startingY: midY, toEndingY: midY, ofColor: UIColor.white, widthOfLine: 1, inView: self)

}



override init(frame: CGRect) {
super.init(frame: frame)
title = UILabel()
self.addSubview(title)

title.textAlignment = .center
title.textColor = UIColor.white
title.translatesAutoresizingMaskIntoConstraints = false

}

required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}

override func updateConstraints() {
if(shouldSetupConstraints) {
// AutoLayout constraints
let xConstraint = NSLayoutConstraint(item: title, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1, constant: 0)
let yConstraint = NSLayoutConstraint(item: title, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1, constant: 0)
self.addConstraints([xConstraint, yConstraint])
shouldSetupConstraints = false
}
super.updateConstraints()
}

func drawLine(startX: Int, toEndingX endX: Int, startingY startY: Int, toEndingY endY: Int, ofColor lineColor: UIColor, widthOfLine lineWidth: CGFloat, inView view: UIView) {

let path = UIBezierPath()
path.move(to: CGPoint(x: startX, y: startY))
path.addLine(to: CGPoint(x: endX, y: endY))

let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
shapeLayer.strokeColor = lineColor.cgColor
shapeLayer.lineWidth = lineWidth

view.layer.addSublayer(shapeLayer)

}
}

Credits:

  • Draw a line with UIBezierPath

  • https://medium.com/written-code/creating-uiviews-programmatically-in-swift-55f5d14502ae

How to draw a line in the simplest way in swift

Try looking into UIBezierPath, it will help you a lot for drawing lines. Here is documentation. Here is an example:

override func drawRect(rect: CGRect) {
let aPath = UIBezierPath()

aPath.move(to: CGPoint(x:<#start x#>, y:<#start y#>))
aPath.addLine(to: CGPoint(x: <#end x#>, y: <#end y#>))

// Keep using the method addLine until you get to the one where about to close the path
aPath.close()

// If you want to stroke it with a red color
UIColor.red.set()
aPath.lineWidth = <#line width#>
aPath.stroke()
}

Make sure you put this code in the drawRect, like in the example above.

If you need to update the drawing just call setNeedsDisplay() to update.

Swift add line above to control

It is simple to add a subview to act as a line. For example:

Swift 4

var lineView = UIView(frame: CGRect(x: 0, y: 100, width: 320, height: 1.0))
lineView.layer.borderWidth = 1.0
lineView.layer.borderColor = UIColor.black.cgColor
self.view.addSubview(lineView)

Objective C

UIView * lineview = [[UIView alloc] initWithFrame:CGRectMake(0, 100,320,1)];
lineview.layer.borderColor = [UIColor blackColor].CGColor;
lineview.layer.borderWidth = 1.0;
[self.view addSubview:lineview];

Or you can refer to this link to add CALayer or draw a view

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

How to draw a line programmatically?

Drawing in iOS can either be done with Core Graphics or Quartz 2D.

Draw a separator line in conjunction with Auto Layout

If you need to add a true one pixel line, don't fool with an image. It's almost impossible. Just use this:

@interface UILine : UIView
@end

@implementation UILine

- (void)awakeFromNib {

CGFloat sortaPixel = 1 / [UIScreen mainScreen].scale;

// recall, the following...
// CGFloat sortaPixel = 1 / self.contentScaleFactor;
// ...does NOT work when loading from storyboard!

UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, sortaPixel)];

line.userInteractionEnabled = NO;
line.backgroundColor = self.backgroundColor;

line.autoresizingMask = UIViewAutoresizingFlexibleWidth;

[self addSubview:line];

self.backgroundColor = [UIColor clearColor];
self.userInteractionEnabled = NO;
}

@end

How to use:

Actually in storyboard, simply make a UIView that is in the exact place, and exact width, you want. (Feel free to use constraints/autolayout as normal.)

Make the view say five pixels high, simply so you can see it clearly, while working.

Make the top of the UIView exactly where you want the single-pixel line. Make the UIView the desired color of the line.

Change the class to UILine. At run time, it will draw a perfect single-pixel line in the exact location on all devices.

(For a vertical line class, simply modify the CGRectMake.)

Hope it helps!

Draw a line realtime with Swift 3.0

You have to begin the image context:

UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0)

You also have to stroke the path:

context?.strokePath()

You also are not drawing the previous image:

imageView.image?.draw(in: view.bounds)

Thus:

func drawLine(from fromPoint: CGPoint, to toPoint: CGPoint) {
UIGraphicsBeginImageContextWithOptions(view.bounds.size, false, 0)

imageView.image?.draw(in: view.bounds)

let context = UIGraphicsGetCurrentContext()

context?.move(to: fromPoint)
context?.addLine(to: toPoint)

context?.setLineCap(CGLineCap.round)
context?.setLineWidth(brushWidth)
context?.setStrokeColor(red: red, green: green, blue: blue, alpha: 1.0)
context?.setBlendMode(CGBlendMode.normal)
context?.strokePath()

imageView.image = UIGraphicsGetImageFromCurrentImageContext()
imageView.alpha = opacity
UIGraphicsEndImageContext()
}

Draw a line with UIBezierPath

Ended up doing it this way:

func drawLineFromPoint(start : CGPoint, toPoint end:CGPoint, ofColor lineColor: UIColor, inView view:UIView) {

//design the path
let path = UIBezierPath()
path.move(to: start)
path.addLine(to: end)

//design path in layer
let shapeLayer = CAShapeLayer()
shapeLayer.path = path.cgPath
shapeLayer.strokeColor = lineColor.CGColor
shapeLayer.lineWidth = 1.0

view.layer.addSublayer(shapeLayer)
}


Related Topics



Leave a reply



Submit