gpt4 book ai didi

Swift 动画圆形进度条

转载 作者:行者123 更新时间:2023-11-28 05:44:13 26 4
gpt4 key购买 nike

我在 Swift 中创建了一个圆形进度条,当用户按住 View 时,它会在 1.5 秒内动画到值 1。但是我想在动画完成后添加一个新的 View Controller ,并在用户提前结束时重新启动我的循环进度条。有人可以帮助我吗?

当用户按住 View 并在释放时停止时,Circulars 进度条正在使用动画。

class CounterView: UIView {
var bgPath: UIBezierPath!
var shapeLayer: CAShapeLayer!
var progressLayer: CAShapeLayer!


override init(frame: CGRect) {
super.init(frame: frame)
bgPath = UIBezierPath()
self.simpleShape()
}

required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
bgPath = UIBezierPath()
self.simpleShape()
}

func simpleShape()
{
createCirclePath()
shapeLayer = CAShapeLayer()
shapeLayer.path = bgPath.cgPath
shapeLayer.lineWidth = 5
shapeLayer.fillColor = nil
shapeLayer.strokeColor = UIColor.clear.cgColor

progressLayer = CAShapeLayer()
progressLayer.path = bgPath.cgPath
progressLayer.lineCap = kCALineCapRound
progressLayer.lineWidth = 5
progressLayer.fillColor = nil
progressLayer.strokeColor = UIColor.yellow.cgColor
progressLayer.strokeEnd = 0.0


self.layer.addSublayer(shapeLayer)
self.layer.addSublayer(progressLayer)
}

private func createCirclePath()
{

let x = self.frame.width/2
let y = self.frame.height/2
let center = CGPoint(x: x, y: y)
print(x,y,center)
bgPath.addArc(withCenter: center, radius: x/CGFloat(2), startAngle: CGFloat(0), endAngle: CGFloat(6.28), clockwise: true)
bgPath.close()
}

var animationCompletedCallback: ((_ isAnimationCompleted: Bool) -> Void)?

func setProgressWithAnimation(duration: TimeInterval, value: Float) {

CATransaction.setCompletionBlock {
if let callBack = self.animationCompletedCallback { callBack(true) }

}

CATransaction.begin()
let animation = CABasicAnimation (keyPath: "strokeEnd")
animation.duration = duration
animation.fromValue = 0
animation.toValue = value
animation.repeatCount = 1
animation.timingFunction = CAMediaTimingFunction (name: kCAMediaTimingFunctionLinear)
progressLayer.strokeEnd = CGFloat(value)
progressLayer.add(animation, forKey: "animateprogress")

CATransaction.commit()
}

func removeLayers() {
shapeLayer.removeAllAnimations()
shapeLayer.removeFromSuperlayer()
progressLayer.removeAllAnimations()
progressLayer.removeFromSuperlayer()
}





}





class ViewController: UIViewController {


@IBOutlet weak var counterView: CounterView!
@IBOutlet weak var holdView: UIView!
var isAnimationCompleted = false


override func viewDidLoad() {
super.viewDidLoad()
addLongPressGesture()
addCounterViewCallback()


}
@objc func longPress(gesture: UILongPressGestureRecognizer) {
if gesture.state == UIGestureRecognizerState.began {
// self.counterView.simpleShape()
self.counterView.setProgressWithAnimation(duration: 1.5, value: 1.0)

}
if gesture.state == UIGestureRecognizerState.ended {
if !isAnimationCompleted {
self.counterView.removeLayers()
}
}
}


func addLongPressGesture(){
let lpgr = UILongPressGestureRecognizer(target: self, action: #selector(longPress(gesture:)))
lpgr.minimumPressDuration = 0
self.holdView.addGestureRecognizer(lpgr)
}

private func addCounterViewCallback() {
counterView.animationCompletedCallback = { [weak self] (isCompleted) in
guard let weakSelf = self else {return}
weakSelf.isAnimationCompleted = isCompleted
weakSelf.addFlashView()
}
}


func addFlashView(){
let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)

let resultViewController = storyBoard.instantiateViewController(withIdentifier: "ResultView") as! Flash

self.present(resultViewController, animated:true, completion:nil)
}

动画完成后添加新的 View Controller ,如果用户释放 View 并再次按住它则重新启动动画。

最佳答案

添加一个回调 以了解动画何时结束。并使用 CATransaction 知道动画何时完成。

var animationCompletedCallback: (() -> Void)?
func setProgressWithAnimation(duration: TimeInterval, value: Float) {

CATransaction.setCompletionBlock {
if let callBack = animationCompletedCallback {
callBack()
}
}

CATransaction.begin()


let animation = CABasicAnimation (keyPath: "strokeEnd")
animation.duration = duration
animation.fromValue = 0
animation.toValue = value
animation.repeatCount = .infinity
animation.timingFunction = CAMediaTimingFunction (name: kCAMediaTimingFunctionLinear)
progressLayer.strokeEnd = CGFloat(value)
progressLayer.add(animation, forKey: "animateprogress")

CATransaction.commit()
}

并在 viewDidLoad() 中的 addLongPressGesture() 之后添加此函数:

private func addCounterViewCallback() {
counterView.animationCompletedCallback = { [weak self] in
guard let weakSelf = self else {return}
weakSelf.addFlashView()
}
}

要删除图层,请使用:

func removeLayers() {
shapeLayer.removeAllAnimations()
shapeLayer.removeFromSuperlayer()
progressLayer.removeAllAnimations()
progressLayer.removeFromSuperlayer()
}

更新 1:

要在用户停止按下时移除动画,您需要像这样在回调中添加变量:

var animationCompletedCallback: ((isAnimationCompleted: Bool) -> Void)?

所以现在 CounterView 中的回调将是:

if let callBack = animationCompletedCallback { callBack(true) }

在你的 Controller 中添加一个变量:var isAnimationCompleted = false

更改 addCounterViewCallback() :

private func addCounterViewCallback() {
counterView.animationCompletedCallback = { [weak self] (isCompleted) in
guard let weakSelf = self else {return}
weakSelf.isAnimationCompleted = isCompleted
weakSelf.addFlashView()
}
}

现在您可以在 longPress() 中添加一个条件:

if gesture.state == UIGestureRecognizerState.ended {
if !isAnimationCompleted {
//Call remove layers code
}
}

更新 2:

CounterView中添加一个变量:

var isAnimationCompleted = true

像这样改变回调:

CATransaction.setCompletionBlock {
if let callBack = self.animationCompletedCallback { callBack(isAnimationCompleted) }
}

在 Controller longPress() 中:

if gesture.state == UIGestureRecognizerState.ended {
if !isAnimationCompleted {
self.counterView.isAnimationCompleted = false
self.counterView.removeLayers()
}
}

addCounterViewCallback() 修改为:

private func addCounterViewCallback() {
counterView.animationCompletedCallback = { [weak self] (isCompleted) in
guard let weakSelf = self else {return}
weakSelf.isAnimationCompleted = isCompleted
if isCompleted {
weakSelf.addFlashView()
}
}
}

关于Swift 动画圆形进度条,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55512032/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com