带虚线的圆圈 uiview [英] circle with dash lines uiview

查看:34
本文介绍了带虚线的圆圈 uiview的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试用虚线画一个圆圈.我能够在矩形中制作线条,但我不知道如何在圆形中制作这些线条.这是我得到的答案,但它在 Objective-C 中:

这种方法的问题是很难让虚线图案对齐(注意3点钟"位置的笨拙虚线).您可以通过确保 lineDashPattern 的两个值加起来等于某个数字来解决这个问题,该数字可以均匀地划分为圆的周长(例如 2π × 半径):

设周长:CGFloat = 2 * .pi * radius让计数 = 30让relativeDashLength:CGFloat = 0.25让 dashLength = 周长/CGFloat(count)shapeLayer.lineDashPattern = [dashLength * relativeDashLength, dashLength * (1 - relativeDashLength)] 作为 [NSNumber]

或者,完全不使用 lineDashPattern,您可以保留实线笔触,并将 path 本身设为一系列小弧线.这样我就可以实现所需的虚线效果,但要确保在我们从 0 旋转到 2π 时将其均匀地分成 count 个小弧:

class DashedCircleView: UIView {私有变量 shapeLayer: CAShapeLayer = {让 shapeLayer = CAShapeLayer()shapeLayer.strokeColor = UIColor.red.cgColorshapeLayer.fillColor = UIColor.clear.cgColorshapeLayer.lineWidth = 10shapeLayer.lineCap = .round返回形状层}()覆盖初始化(框架:CGRect = .zero){super.init(框架:框架)配置()}需要初始化?(编码器aDecoder:NSCoder){super.init(编码器:aDecoder)配置()}覆盖 func layoutSubviews() {super.layoutSubviews()更新路径()}}私人扩展 DashedCircleView {功能配置(){layer.addSublayer(shapeLayer)}功能更新路径(){让 rect = bounds.insetBy(dx: shapeLayer.lineWidth/2, dy: shapeLayer.lineWidth/2)让半径 = min(rect.width, rect.height)/2让中心 = CGPoint(x: rect.midX, y: rect.midY)让路径 = UIBezierPath()让计数 = 30let relativeDashLength: CGFloat = 0.25//0 到 1 之间的值让增量:CGFloat = .pi * 2/CGFloat(count)对于 i 在 0 ..<数数 {让 startAngle = 增量 * CGFloat(i)让 endAngle = startAngle + relativeDashLength * 增量path.move(to: CGPoint(x: center.x + radius * cos(startAngle),y:center.y + 半径 * sin(startAngle)))path.addArc(withCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, 顺时针: true)}shapeLayer.path = path.cgPath}}

结果:

I am trying to make a circle with dash lines. I am able to make lines in rectangle but I don't know how to make these in circle. Here is answer I got but it's in Objective-C: UIView Draw Circle with Dotted Line Border

Here is my code which makes a rectangle with dashed lines.

func addDashedBorder() {
    let color = UIColor.red.cgColor

    let shapeLayer:CAShapeLayer = CAShapeLayer()
    let frameSize = self.frame.size
    let shapeRect = CGRect(x: 0, y: 0, width: frameSize.width, height: frameSize.height)

    shapeLayer.bounds = shapeRect
    shapeLayer.position = CGPoint(x: frameSize.width/2, y: frameSize.height/2)
    shapeLayer.fillColor = UIColor.clear.cgColor
    shapeLayer.strokeColor = color
    shapeLayer.lineWidth = 2
    shapeLayer.lineJoin = CAShapeLayerLineJoin.round
    shapeLayer.lineDashPattern = [6,3]
    shapeLayer.path = UIBezierPath(roundedRect: shapeRect, cornerRadius: 5).cgPath

    self.layer.addSublayer(shapeLayer)
}

解决方案

Certainly you can just render your circular UIBezierPath with the selected dash pattern:

class DashedCircleView: UIView {
    private var shapeLayer: CAShapeLayer = {
        let shapeLayer = CAShapeLayer()
        shapeLayer.strokeColor = UIColor.red.cgColor
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineWidth = 10
        shapeLayer.lineCap = .round
        shapeLayer.lineDashPattern = [20, 60]
        return shapeLayer
    }()

    override init(frame: CGRect = .zero) {
        super.init(frame: frame)
        configure()
    }

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

    override func layoutSubviews() {
        super.layoutSubviews()
        updatePath()
    }
}

private extension DashedCircleView {
    func configure() {
        layer.addSublayer(shapeLayer)
    }

    func updatePath() {
        let rect = bounds.insetBy(dx: shapeLayer.lineWidth / 2, dy: shapeLayer.lineWidth / 2)
        let radius = min(rect.width, rect.height) / 2
        let center = CGPoint(x: rect.midX, y: rect.midY)
        let path = UIBezierPath(arcCenter: center, radius: radius, startAngle: 0, endAngle: .pi * 2, clockwise: true)
        shapeLayer.path = path.cgPath
    }
}

That yields:

The problem with that approach is that it’s hard to get the dashed pattern to line up (notice the awkward dashing at the "3 o’clock" position). You can fix that by making sure that the two values of lineDashPattern add up to some number that evenly divides into the circumference of the circle (e.g. 2π × radius):

let circumference: CGFloat = 2 * .pi * radius
let count = 30
let relativeDashLength: CGFloat = 0.25
let dashLength = circumference / CGFloat(count)
shapeLayer.lineDashPattern = [dashLength * relativeDashLength, dashLength * (1 - relativeDashLength)] as [NSNumber]

Alternatively, rather than using lineDashPattern at all, you can instead keep a solid stroke and make the path, itself, as a series of small arcs. That way I can achieve the desired dashed effect, but ensuring it’s evenly split into count little arcs as we rotate from 0 to 2π:

class DashedCircleView: UIView {
    private var shapeLayer: CAShapeLayer = {
        let shapeLayer = CAShapeLayer()
        shapeLayer.strokeColor = UIColor.red.cgColor
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineWidth = 10
        shapeLayer.lineCap = .round
        return shapeLayer
    }()

    override init(frame: CGRect = .zero) {
        super.init(frame: frame)
        configure()
    }

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

    override func layoutSubviews() {
        super.layoutSubviews()
        updatePath()
    }
}

private extension DashedCircleView {
    func configure() {
        layer.addSublayer(shapeLayer)
    }

    func updatePath() {
        let rect = bounds.insetBy(dx: shapeLayer.lineWidth / 2, dy: shapeLayer.lineWidth / 2)
        let radius = min(rect.width, rect.height) / 2
        let center = CGPoint(x: rect.midX, y: rect.midY)

        let path = UIBezierPath()
        let count = 30
        let relativeDashLength: CGFloat = 0.25 // a value between 0 and 1
        let increment: CGFloat = .pi * 2 / CGFloat(count)

        for i in 0 ..< count {
            let startAngle = increment * CGFloat(i)
            let endAngle = startAngle + relativeDashLength * increment
            path.move(to: CGPoint(x: center.x + radius * cos(startAngle), 
                                  y: center.y + radius * sin(startAngle)))
            path.addArc(withCenter: center, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: true)
        } 
        shapeLayer.path = path.cgPath
    }
}

That yields:

这篇关于带虚线的圆圈 uiview的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆