Draw dotted (not dashed!) line, with IBDesignable in 2017

前端 未结 10 1654
死守一世寂寞
死守一世寂寞 2020-11-28 03:25

It\'s easy to draw a dashed line with UIKit. So:

CGFloat dashes[] = {4, 2};
[path setLineDash:dashes count:2 phase:0];
[path stroke];


        
相关标签:
10条回答
  • 2020-11-28 04:20

    Working fine with the below code,

    layer.path = linePath.cgPath
    layer.lineWidth = 3
    layer.lineDashPattern = [1,layer.lineWidth*2] as [NSNumber]
    layer.lineCap = "round"
    
    0 讨论(0)
  • 2020-11-28 04:21

    Not a full answer, just a very important gotcha that James P raised in a comment on the favourite answer:

    He wrote:

    I've found setting the on length to 0.01 gives you a circular dot, whereas they are slightly elongated when using 0.

    For example,

       let dashes: [CGFloat] = [0.001, path.lineWidth * 2]
    
    0 讨论(0)
  • 2020-11-28 04:26

    Hey it's maybe too late to answer on that question. but if you agree I would like to share an easy way to resolve that to the developers that will maybe face that problem in the future. so I guess that the easiest solution using @IBDesignable. You need just to create that class

    import UIKit
    
    @IBDesignable class DottedVertical: UIView {
    
        @IBInspectable var dotColor: UIColor = UIColor.red
        @IBInspectable var lowerHalfOnly: Bool = false
    
        override func draw(_ rect: CGRect) {
    
            // say you want 8 dots, with perfect fenceposting:
            let totalCount = 8 + 8 - 1
            let fullHeight = bounds.size.height
            let width = bounds.size.width
            let itemLength = fullHeight / CGFloat(totalCount)
    
            let path = UIBezierPath()
    
            let beginFromTop = CGFloat(0.0)
            let top = CGPoint(x: width/2, y: beginFromTop)
            let bottom = CGPoint(x: width/2, y: fullHeight)
    
            path.move(to: top)
            path.addLine(to: bottom)
    
            path.lineWidth = width
            //DASHED SIMPLE LINE
            //let dashes: [CGFloat] = [itemLength, itemLength]
            //path.setLineDash(dashes, count: dashes.count, phase: 0)
    
            // for ROUNDED dots, simply change to....
            let dashes: [CGFloat] = [0.0, itemLength * 1.1]
            path.lineCapStyle = CGLineCap.round
            path.setLineDash(dashes, count: dashes.count, phase: 0)
    
            dotColor.setStroke()
            path.stroke()
        }
    }
    

    And then append it to your view in the storyboard like that

    Once you've done you cold customize the space between the layers from this line let dashes: [CGFloat] = [0.0, itemLength * 1.1] --> Line 39 in the DottedVertical class. or if you want to customize the width of the layer you need just to edit your line view width from your storyboard

    0 讨论(0)
  • 2020-11-28 04:27

    Set the line cap style to round and set the “on” length to a tiny number.

    Swift playground example:

    import UIKit
    import PlaygroundSupport
    
    let path = UIBezierPath()
    path.move(to: CGPoint(x:10,y:10))
    path.addLine(to: CGPoint(x:290,y:10))
    path.lineWidth = 8
    
    let dashes: [CGFloat] = [0.001, path.lineWidth * 2]
    path.setLineDash(dashes, count: dashes.count, phase: 0)
    path.lineCapStyle = CGLineCap.round
    
    UIGraphicsBeginImageContextWithOptions(CGSize(width:300, height:20), false, 2)
    
    UIColor.white.setFill()
    UIGraphicsGetCurrentContext()!.fill(.infinite)
    
    UIColor.black.setStroke()
    path.stroke()
    
    let image = UIGraphicsGetImageFromCurrentImageContext()
    let view = UIImageView(image: image)
    PlaygroundPage.current.liveView = view
    
    UIGraphicsEndImageContext()
    

    Result:

    dots


    For objective-C, using the same example class as in the question, simply add

    CGContextSetLineCap(cx, kCGLineCapRound);
    

    before the call to CGContextStrokePath, and change the ra array values to match my Swift code.

    0 讨论(0)
提交回复
热议问题