我试图创建一个循环的进程视图,有中风外.但我的笔划是从视图的内部开始的,而不是从外部开始的,就像边界.怎么解决呢?

My code:

var progressLayer = CAShapeLayer()
var trackLayer = CAShapeLayer()

var progressLineWidth: CGFloat = 20
var progressColor = UIColor.green
var progress: Float = 0.5

let circlePath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0 - 2, y: frame.size.height / 2.0 - 2), radius: (frame.size.width) / 2, startAngle: -(.pi / 2), endAngle: .pi * 1.5, clockwise: true)

trackLayer.path = circlePath.cgPath
trackLayer.strokeColor = UIColor.gray.cgColor
trackLayer.lineWidth = 10
trackLayer.strokeEnd = 1.0
trackLayer.lineDashPattern = [4,4]
trackLayer.fillColor = UIColor.red.cgColor
layer.addSublayer(trackLayer)

progressLayer.path = circlePath.cgPath
progressLayer.fillColor = UIColor.clear.cgColor
progressLayer.strokeColor = progressColor.cgColor
progressLayer.lineWidth = progressLineWidth
progressLayer.strokeEnd = CGFloat(progress)
progressLayer.strokeStart = 0
progressLayer.lineDashPattern = [4,4]
layer.addSublayer(progressLayer)

Result:

enter image description here

What I want to achive:

enter image description here

Gray and green strokes should start from the outside of the red circle.

推荐答案

Demo

您可以用简单的蒙版减go 中间的圆圈,如下所示:

let maskLayer = CAShapeLayer()
maskLayer.path = UIBezierPath(rect: self.bounds).cgPath.subtracting(circlePath.cgPath)
layer.mask = maskLayer

完整的工作代码:

class CircularProgressBarView: UIView {
    var progress: CGFloat = 0 { didSet { layoutSubviews() } }
    var progressLineWidth: CGFloat = 20 { didSet { layoutSubviews() } }
    var progressColor = UIColor.green { didSet { layoutSubviews() } }
    var pattern: [NSNumber] = [4,4] { didSet { layoutSubviews() } }

    private var customLayer = CALayer()

    override func layoutSubviews() {
        super.layoutSubviews()

        customLayer.removeFromSuperlayer()
        customLayer = CALayer()

        let bounds = CGRect(
            x: progressLineWidth,
            y: progressLineWidth,
            width: bounds.width - progressLineWidth*2,
            height: bounds.height - progressLineWidth*2
        )

        let circlePath = UIBezierPath(ovalIn: bounds)

        let trackLayer = CAShapeLayer()
        trackLayer.path = circlePath.cgPath
        trackLayer.strokeColor = UIColor.gray.cgColor
        trackLayer.lineWidth = progressLineWidth
        trackLayer.lineDashPattern = pattern
        trackLayer.fillColor = UIColor.red.cgColor
        customLayer.addSublayer(trackLayer)

        let progressLayer = CAShapeLayer()
        progressLayer.path = circlePath.cgPath
        progressLayer.fillColor = UIColor.clear.cgColor
        progressLayer.strokeColor = progressColor.cgColor
        progressLayer.lineWidth = progressLineWidth * 2
        progressLayer.strokeEnd = progress
        progressLayer.lineDashPattern = pattern
        customLayer.addSublayer(progressLayer)

        let containerPath = UIBezierPath(rect: self.bounds).cgPath
        let maskLayer = CAShapeLayer()
        maskLayer.path = containerPath.subtracting(circlePath.cgPath)
        customLayer.mask = maskLayer

        layer.addSublayer(customLayer)
    }
}

当然,您可以旋转整个图层(或视图),使其从12点开始

Ios相关问答推荐

(Flutter)获取图像从图像拾取器保存和加载问题

在SwiftUI中动态隐藏列表的空部分

如何在不将应用程序留在SwiftUI上的情况下更改语言?

Xcode 15模拟器用x86_64编译

如何在 Android 上的 Flutter 应用中录制内部音频?

如果使用 .onAppear 设置,为什么 SwiftUI Picker 不显示正确的选定值

部分保留 UITextField 中的占位符

iOS应用程序崩溃,必需条件为false:isformatsamplerateandchannelcountvalid(format)

为 ColorPicker 创建一个名为 Color 的计算变量的绑定

如何在 SwiftUI 的 TabView 中添加底部曲线?

如何在 SwiftUI 中只显示一次随机数组的项目?

`Task` 在内部调用异步函数时阻塞主线程

将 SwiftUI 与 @AppStorage 和动态函数调用一起使用

iOS,Swift 5,AppDelegate open url / .onOpenUrl - 如何找到调用我的自定义方案的调用应用程序

滑动列表项以获取更多选项(Flutter)

SwiftUI 视图 - viewDidLoad()?

在滚动视图中使用动态大小的控制器调整容器视图的大小

try 在 iOS 中处理后退导航按钮操作

关闭通过模态 segue 显示的视图

iOS SDK - 以编程方式生成 PDF 文件