简体   繁体   English

Swift 5 中的圆形进度条

[英]Circular progress bar in Swift 5

I had trying do a circular progress bar, but when I run the app, it crashes and show me the next error:我曾尝试做一个圆形进度条,但是当我运行该应用程序时,它崩溃并显示下一个错误:

Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file /Users/marcoalonso/Documents/SWIFT_PROJECTS/CircularProgressView/CircularProgressView/ViewController.swift, line 15 2020-04-18 19:26:48.103695-0500 CircularProgressView[3634:99760] Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value: file /Users/marcoalonso/Documents/SWIFT_PROJECTS/CircularProgressView/CircularProgressView/ViewController.swift, line 15致命错误:在隐式展开可选值时意外发现 nil:文件 /Users/marcoalonso/Documents/SWIFT_PROJECTS/CircularProgressView/CircularProgressView/ViewController.swift,第 15 行 2020-04-18 19:26:405.10369356-03 ] 致命错误:在隐式展开可选值时意外发现 nil:文件 /Users/marcoalonso/Documents/SWIFT_PROJECTS/CircularProgressView/CircularProgressView/ViewController.swift,第 15 行

I have only 2 files which are:我只有 2 个文件,它们是:

import UIKit
class ViewController: UIViewController {
    @IBOutlet weak var containerView: UIView!
    var circularView: CircularProgressView!
    var duration: TimeInterval!
    override func viewDidLoad() {
        super.viewDidLoad()
        circularView.center = view.center
        containerView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
        view.addSubview(circularView)
    }

    @objc func handleTap() {
        duration = 3.0
        circularView.progressAnimation(duration: duration)
    }
}

and CircularProgressView.swift:和 CircularProgressView.swift:

import UIKit
class CircularProgressView: UIView {
    // First create two layer properties
    private var circleLayer = CAShapeLayer()
    private var progressLayer = CAShapeLayer()
    override init(frame: CGRect) {
        super.init(frame: frame)
        createCircularPath()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        createCircularPath()
    }
    func createCircularPath() {
        let circularPath = UIBezierPath(arcCenter: CGPoint(x: frame.size.width / 2.0, y: frame.size.height / 2.0), radius: 80, startAngle: -.pi / 2, endAngle: 3 * .pi / 2, clockwise: true)
        circleLayer.path = circularPath.cgPath
        circleLayer.fillColor = UIColor.clear.cgColor
        circleLayer.lineCap = .round
        circleLayer.lineWidth = 20.0
        circleLayer.strokeColor = UIColor.black.cgColor
        progressLayer.path = circularPath.cgPath
        progressLayer.fillColor = UIColor.clear.cgColor
        progressLayer.lineCap = .round
        progressLayer.lineWidth = 10.0
        progressLayer.strokeEnd = 0
        progressLayer.strokeColor = UIColor.red.cgColor
        layer.addSublayer(circleLayer)
        layer.addSublayer(progressLayer)
    }
    func progressAnimation(duration: TimeInterval) {
        let circularProgressAnimation = CABasicAnimation(keyPath: "strokeEnd")
        circularProgressAnimation.duration = duration
        circularProgressAnimation.toValue = 1.0
        circularProgressAnimation.fillMode = .forwards
        circularProgressAnimation.isRemovedOnCompletion = false
        progressLayer.add(circularProgressAnimation, forKey: "progressAnim")
    }
}

I hope someone can help me please!我希望有人可以帮助我!

I think maybe it`sa problem with storyboard so, this is my story board file我想这可能是 storyboard 的问题所以,这是我的故事板文件在此处输入图像描述

Here you're using a nil circularView to assign center property and that's fail在这里,您使用 nil circularView来分配center属性,这是失败的

override func viewDidLoad() {
    super.viewDidLoad()
    circularView.center = view.center
    containerView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
    view.addSubview(circularView)
}

You can remove that line and assign center when circularView is not nil or initialize circularView first and then use center.您可以在circularView不为 nil 时删除该行并分配中心,或者先初始化circularView然后使用中心。

Just initialise circularView in your ViewController:只需在 ViewController 中初始化 circularView:

replace:代替:

var circularView: CircularProgressView!

with:和:

var circularView = CircularProgressView()

You have not initialised any object for circularView.您还没有为循环视图初始化任何 object。 You have only said that circularView will have a object of type CircularProgressView but you have not stored any object there.您只说过 circleView 将有一个 CircularProgressView 类型的 object 但您没有在那里存储任何 object 。 So before doing anything using circularView initialise it with:因此,在使用 circularView 进行任何操作之前,先使用以下命令对其进行初始化:

circularView = CircularProgressView() 

For more clearity your code should be like this为了更清楚你的代码应该是这样的

import UIKit
class ViewController: UIViewController {
    @IBOutlet weak var containerView: UIView!
    var circularView: CircularProgressView!
    var duration: TimeInterval!
    override func viewDidLoad() {
        super.viewDidLoad()
        circularView = CircularProgressView()
        circularView.center = view.center
        containerView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
        view.addSubview(circularView)
    }

    @objc func handleTap() {
        duration = 3.0
        circularView.progressAnimation(duration: duration)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM