I want to know how to make a dashed line in swift like this: - - - - - - - - instead of a regular straight line like this: ----------------, I know that i can make multiple lines but that will require so much unnecessary code if i can just write it in 1 line. Btw it has to be in CoreGraphics.
You create Dashed Lines the same way as Objective-C, except that you'll use Swift.
Here is how you do it using UIBezierPath:
let path = UIBezierPath()
let p0 = CGPoint(x: self.bounds.minX, y: self.bounds.midY)
path.move(to: p0)
let p1 = CGPoint(x: self.bounds.maxX, y: self.bounds.midY)
path.addLine(to: p1)
let dashes: [ CGFloat ] = [ 16.0, 32.0 ]
path.setLineDash(dashes, count: dashes.count, phase: 0.0)
path.lineWidth = 8.0
path.lineCapStyle = .butt
UIColor.magenta.set()
path.stroke()
Here is how to draw Dotted Lines using UIBezierPath:
let path = UIBezierPath()
let p0 = CGPointMake(CGRectGetMinX(self.bounds), CGRectGetMidY(self.bounds))
path.moveToPoint(p0)
let p1 = CGPointMake(CGRectGetMaxX(self.bounds), CGRectGetMidY(self.bounds))
path.addLineToPoint(p1)
let dashes: [ CGFloat ] = [ 0.0, 16.0 ]
path.setLineDash(dashes, count: dashes.count, phase: 0.0)
path.lineWidth = 8.0
path.lineCapStyle = .Round
UIColor.magentaColor().set()
path.stroke()
Here is how to draw Dashed Lines Using CGContext:
let context: CGContext = UIGraphicsGetCurrentContext()!
let p0 = CGPointMake(CGRectGetMinX(self.bounds), CGRectGetMidY(self.bounds))
CGContextMoveToPoint(context, p0.x, p0.y)
let p1 = CGPointMake(CGRectGetMaxX(self.bounds), CGRectGetMidY(self.bounds))
CGContextAddLineToPoint(context, p1.x, p1.y)
let dashes: [ CGFloat ] = [ 16.0, 32.0 ]
CGContextSetLineDash(context, 0.0, dashes, dashes.count)
CGContextSetLineWidth(context, 8.0)
CGContextSetLineCap(context, .Butt)
UIColor.blueColor().set()
CGContextStrokePath(context)
Swift 4
@IBOutlet var dashedView: UIView!
func drawDottedLine(start p0: CGPoint, end p1: CGPoint, view: UIView) {
let shapeLayer = CAShapeLayer()
shapeLayer.strokeColor = UIColor.lightGray.cgColor
shapeLayer.lineWidth = 1
shapeLayer.lineDashPattern = [7, 3] // 7 is the length of dash, 3 is length of the gap.
let path = CGMutablePath()
path.addLines(between: [p0, p1])
shapeLayer.path = path
view.layer.addSublayer(shapeLayer)
}
Call function
drawDottedLine(start: CGPoint(x: dashedView.bounds.minX, y: dashedView.bounds.minY), end: CGPoint(x: dashedView.bounds.maxX, y: dashedView.bounds.minY), view: dashedView)
With the above you will have a straight line, you can also change points as you wish, for example if you change the end point's y from dashedView.bounds.minY
to dashedView.bounds.maxY
you will have diagonal.
If you will use it in a subclass of UIView you won't have the outlet so you will use it with self instead.
dashedView
background .clear if you want the non-dotted line to disappear if you drew that with constraints in the storyboard –
Guess You create Dashed Lines the same way as Objective-C, except that you'll use Swift.
Here is how you do it using UIBezierPath:
let path = UIBezierPath()
let p0 = CGPoint(x: self.bounds.minX, y: self.bounds.midY)
path.move(to: p0)
let p1 = CGPoint(x: self.bounds.maxX, y: self.bounds.midY)
path.addLine(to: p1)
let dashes: [ CGFloat ] = [ 16.0, 32.0 ]
path.setLineDash(dashes, count: dashes.count, phase: 0.0)
path.lineWidth = 8.0
path.lineCapStyle = .butt
UIColor.magenta.set()
path.stroke()
Here is how to draw Dotted Lines using UIBezierPath:
let path = UIBezierPath()
let p0 = CGPointMake(CGRectGetMinX(self.bounds), CGRectGetMidY(self.bounds))
path.moveToPoint(p0)
let p1 = CGPointMake(CGRectGetMaxX(self.bounds), CGRectGetMidY(self.bounds))
path.addLineToPoint(p1)
let dashes: [ CGFloat ] = [ 0.0, 16.0 ]
path.setLineDash(dashes, count: dashes.count, phase: 0.0)
path.lineWidth = 8.0
path.lineCapStyle = .Round
UIColor.magentaColor().set()
path.stroke()
Here is how to draw Dashed Lines Using CGContext:
let context: CGContext = UIGraphicsGetCurrentContext()!
let p0 = CGPointMake(CGRectGetMinX(self.bounds), CGRectGetMidY(self.bounds))
CGContextMoveToPoint(context, p0.x, p0.y)
let p1 = CGPointMake(CGRectGetMaxX(self.bounds), CGRectGetMidY(self.bounds))
CGContextAddLineToPoint(context, p1.x, p1.y)
let dashes: [ CGFloat ] = [ 16.0, 32.0 ]
CGContextSetLineDash(context, 0.0, dashes, dashes.count)
CGContextSetLineWidth(context, 8.0)
CGContextSetLineCap(context, .Butt)
UIColor.blueColor().set()
CGContextStrokePath(context)
By Using Custom Class inherited from UIView also supports Storyboard.
All you need to do is make a view in storyboard assign class to that view and see the magic in storyboard.
@IBDesignable
class DashedLineView : UIView {
@IBInspectable var perDashLength: CGFloat = 2.0
@IBInspectable var spaceBetweenDash: CGFloat = 2.0
@IBInspectable var dashColor: UIColor = UIColor.lightGray
override func draw(_ rect: CGRect) {
super.draw(rect)
let path = UIBezierPath()
if height > width {
let p0 = CGPoint(x: self.bounds.midX, y: self.bounds.minY)
path.move(to: p0)
let p1 = CGPoint(x: self.bounds.midX, y: self.bounds.maxY)
path.addLine(to: p1)
path.lineWidth = width
} else {
let p0 = CGPoint(x: self.bounds.minX, y: self.bounds.midY)
path.move(to: p0)
let p1 = CGPoint(x: self.bounds.maxX, y: self.bounds.midY)
path.addLine(to: p1)
path.lineWidth = height
}
let dashes: [ CGFloat ] = [ perDashLength, spaceBetweenDash ]
path.setLineDash(dashes, count: dashes.count, phase: 0.0)
path.lineCapStyle = .butt
dashColor.set()
path.stroke()
}
private var width : CGFloat {
return self.bounds.width
}
private var height : CGFloat {
return self.bounds.height
}
}
backgroundColor = .clear
to make it work properly on every color of view –
Fever IBInspectable bgColor
is better option instead of just giving statically clear color. –
Receivership Here's an easy to use UIView that draws a dashed line.
I took @Fan Jin's answer and made an UIView subclass that should work just fine with Auto Layout.
Swift 5.3, Xcode 12
import UIKit
public class DashedView: UIView {
public struct Configuration {
public var color: UIColor
public var dashLength: CGFloat
public var dashGap: CGFloat
public init(
color: UIColor,
dashLength: CGFloat,
dashGap: CGFloat) {
self.color = color
self.dashLength = dashLength
self.dashGap = dashGap
}
static let `default`: Self = .init(
color: .lightGray,
dashLength: 7,
dashGap: 3)
}
// MARK: - Properties
/// Override to customize height
public class var lineHeight: CGFloat { 1.0 }
override public var intrinsicContentSize: CGSize {
CGSize(width: UIView.noIntrinsicMetric, height: Self.lineHeight)
}
public final var config: Configuration = .default {
didSet {
drawDottedLine()
}
}
private var dashedLayer: CAShapeLayer?
// MARK: - Life Cycle
override public func layoutSubviews() {
super.layoutSubviews()
// We only redraw the dashes if the width has changed.
guard bounds.width != dashedLayer?.frame.width else { return }
drawDottedLine()
}
// MARK: - Drawing
private func drawDottedLine() {
if dashedLayer != nil {
dashedLayer?.removeFromSuperlayer()
}
dashedLayer = drawDottedLine(
start: bounds.origin,
end: CGPoint(x: bounds.width, y: bounds.origin.y),
config: config)
}
}
// Thanks to: https://mcmap.net/q/381621/-how-to-make-a-dashed-line-in-swift
private extension DashedView {
func drawDottedLine(
start: CGPoint,
end: CGPoint,
config: Configuration) -> CAShapeLayer {
let shapeLayer = CAShapeLayer()
shapeLayer.strokeColor = config.color.cgColor
shapeLayer.lineWidth = Self.lineHeight
shapeLayer.lineDashPattern = [config.dashLength as NSNumber, config.dashGap as NSNumber]
let path = CGMutablePath()
path.addLines(between: [start, end])
shapeLayer.path = path
layer.addSublayer(shapeLayer)
return shapeLayer
}
}
enum Orientation { case HORIZONTAL case VERTICAL }
Thanks again. –
Spiniferous My extension method built from @FanJins answer
extension UIView {
func createDashedLine(from point1: CGPoint, to point2: CGPoint, color: UIColor, strokeLength: NSNumber, gapLength: NSNumber, width: CGFloat) {
let shapeLayer = CAShapeLayer()
shapeLayer.strokeColor = color.cgColor
shapeLayer.lineWidth = width
shapeLayer.lineDashPattern = [strokeLength, gapLength]
let path = CGMutablePath()
path.addLines(between: [point1, point2])
shapeLayer.path = path
layer.addSublayer(shapeLayer)
}
}
Then calling method looks something like this:
let topPoint = CGPoint(x: view.frame.midX, y: view.bounds.minY)
let bottomPoint = CGPoint(x: view.frame.midX, y: view.bounds.maxY)
view.createDashedLine(from: topPoint, to: bottomPoint, color: .black, strokeLength: 4, gapLength: 6, width: 2)
Pretty easy UIView Extension for SWIFT 4.2:
extension UIView {
private static let lineDashPattern: [NSNumber] = [2, 2]
private static let lineDashWidth: CGFloat = 1.0
func makeDashedBorderLine() {
let path = CGMutablePath()
let shapeLayer = CAShapeLayer()
shapeLayer.lineWidth = UIView.lineDashWidth
shapeLayer.strokeColor = UIColor.lightGray.cgColor
shapeLayer.lineDashPattern = UIView.lineDashPattern
path.addLines(between: [CGPoint(x: bounds.minX, y: bounds.height/2),
CGPoint(x: bounds.maxX, y: bounds.height/2)])
shapeLayer.path = path
layer.addSublayer(shapeLayer)
}
}
Objective C
@user3230875 answer helped me to understand what's needed to draw a dotted line.
so I hope this answer might help an Obj-C
seeker
//dashed line
path = [UIBezierPath bezierPath];
[path moveToPoint:CGPointMake(dashedLineStartX, dashedLineStartY)];
[path addLineToPoint:CGPointMake(dashedLineEndX, dashedLineEndY)];
path.lineWidth = 5;
[color setStroke];
CGFloat dashes[] = {4.0,8.0};
[path setLineDash:dashes count:2 phase:0.0];
path.lineCapStyle = kCGLineCapButt;
[path stroke];
modified version of @clément-cardonnel 's answer.
Enhanced with isVertical option and IBInspectable properties
class DottedLineView : UIView {
@IBInspectable var perDashLength: CGFloat = 2.0
@IBInspectable var spaceBetweenDash: CGFloat = 2.0
@IBInspectable var dashColor: UIColor = UIColor.gray
@IBInspectable var lineWidth: CGFloat = 2.0
@IBInspectable var isVertical: Bool = false
private var dashedLayer: CAShapeLayer?
override public func layoutSubviews() {
super.layoutSubviews()
guard bounds.width != dashedLayer?.frame.width,
bounds.height != dashedLayer?.frame.height
else { return }
drawDottedLine()
}
private func drawDottedLine() {
if dashedLayer != nil {
dashedLayer?.removeFromSuperlayer()
}
var startPoint = CGPoint(
x: bounds.width / 2 + lineWidth / 2,
y: 0
)
var endPoint = CGPoint(
x: bounds.width / 2 + lineWidth / 2,
y: bounds.height
)
if !isVertical {
startPoint = CGPoint(
x: 0,
y: bounds.height / 2 + lineWidth / 2
)
endPoint = CGPoint(
x: bounds.width,
y: bounds.height / 2 + lineWidth / 2
)
}
dashedLayer = drawDottedLine(
startPoint: startPoint,
endPoint: endPoint
)
}
private func drawDottedLine(startPoint: CGPoint, endPoint: CGPoint) -> CAShapeLayer {
let shapeLayer = CAShapeLayer()
shapeLayer.strokeColor = dashColor.cgColor
shapeLayer.lineWidth = self.lineWidth
shapeLayer.lineDashPattern = [perDashLength as NSNumber, spaceBetweenDash as NSNumber]
let path = CGMutablePath()
path.addLines(between: [startPoint, endPoint])
shapeLayer.path = path
layer.addSublayer(shapeLayer)
return shapeLayer
}
}
© 2022 - 2024 — McMap. All rights reserved.