【问题标题】:How to make a dashed line in swift?如何快速制作虚线?
【发布时间】:2016-08-15 19:13:56
【问题描述】:

我想知道如何像这样快速制作虚线: - - - - - - - - 而不是像这样的常规直线:--------------- -,我知道我可以写多行,但是如果我可以在 1 行中编写它,那将需要很多不必要的代码。顺便说一句,它必须在 CoreGraphics 中。

【问题讨论】:

  • 你能显示你当前的行创建代码吗?
  • 查找 CGContextSetLineDash.

标签: ios iphone swift core-graphics line


【解决方案1】:

斯威夫特 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)
}

调用函数

drawDottedLine(start: CGPoint(x: dashedView.bounds.minX, y: dashedView.bounds.minY), end: CGPoint(x: dashedView.bounds.maxX, y: dashedView.bounds.minY), view: dashedView)

有了上面你会得到一条直线,你也可以随心所欲地改变点,例如如果你把终点的y从dashedView.bounds.minY改为dashedView.bounds.maxY你就会有对角线。

如果您将在 UIView 的子类中使用它,您将没有插座,因此您将使用 self 代替。

【讨论】:

  • 此处层未定义
  • 嗨@VineeshTP,该层来自“view.layer”您希望添加虚线的视图。
  • 如果我们在 storyboard 中选择了 iphone 8,然后,如果我们应用此代码并在 iPhone 5s 上运行它,那么虚线超出了宽度。
  • 虚线的起点和终点附在视图上,所以请确保您的视图在 iPhone 5s 中不会超出边界。
  • 如果您希望在情节提要中使用约束条件绘制非虚线,则您还必须将dashedView 背景设为清晰
【解决方案2】:

创建虚线的方式与 Objective-C 相同,不同之处在于您将使用 Swift。

这是使用 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()

以下是如何使用 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()

以下是使用 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)

【讨论】:

  • 当我传递两个绑定为参数的按钮时,线没有出现,如何在两个 UIbutton 之间绘制虚线。这是我的代码 let path = UIBezierPath() let p0 = CGPointMake(CGRectGetMinX(self.button1.bounds), CGRectGetMidY(self.button1.bounds)) path.moveToPoint(p0) let p1 = CGPointMake(CGRectGetMaxX(self.button2. bounds), CGRectGetMidY(self.button2.bounds)) path.addLineToPoint(p1)
【解决方案3】:

通过使用继承自 UIView 的自定义类也支持 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 以使其在每种颜色的视图上都能正常工作
  • @Salmaan 我认为IBInspectable bgColor 是更好的选择,而不是仅仅给出静态清晰的颜色。
【解决方案4】:

这是一个易于使用的绘制虚线的 UIView。

我接受了@Fan Jin 的回答,并制作了一个 UIView 子类,它应该可以很好地与 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://stackoverflow.com/a/49305154/4802021
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 } 再次感谢。
【解决方案5】:

我从@FanJins 答案构建的扩展方法

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

然后调用方法看起来像这样:

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)

【讨论】:

    【解决方案6】:

    SWIFT 4.2 的非常简单的 UIView 扩展:

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

    【讨论】:

      【解决方案7】:

      Objective C

      @user3230875 回答帮助我理解了画虚线需要什么。
      所以我希望这个答案可能对Obj-C 寻求者有所帮助

      //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];
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-03-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多