如果在添加动画之前调用 startAnimation(),UIViewPropertyAnimator 会中断

问题描述

根据 WWDC17 Advanced Animations with UIKit Session 230,在添加动画之前在 startAnimation()调用 UIViewPropertyAnimator 将在稍后添加动画时立即运行动画。

但是,我发现这由于某种原因破坏了我的代码

这是一个错误吗?

演示

我写了一个小演示来演示这一点 - 该视图只允许向右拖动以调高亮度,向左拖动以降低亮度。

import UIKit

class ViewController: UIViewController {

    override func loadView() {
        self.view = View()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
}

class View: UIView {
    // views
    lazy var label: UILabel = {
        let v = UILabel()
        v.text = "Swipe -> to turn up brightness"
        v.autoresizingMask = [.flexibleHeight,.flexibleWidth]
        v.textAlignment = .center
        return v
    }()
    
    lazy var overlay: UIView = {
        let v = UIView()
        v.backgroundColor = UIColor(red: 0,green: 0,blue: 0,alpha: 0.5)
        v.alpha = overlayAlpha
        return v
    }()
    
    // states
    private var overlayAlpha: CGFloat = 1
    
    // var
    private var initialAlpha: CGFloat = 0
    private var initialLocation: CGPoint = .zero
    private var totalTranslation: CGFloat = .zero
    
    init() {
        super.init(frame: .zero)
        self.loadViews()
        self.setupGestures()
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    override func layoutSubviews() {
        backgroundColor = .white
        overlay.frame = self.bounds
        label.frame = self.bounds
    }
}

extension View {
    private func loadViews() {
        addSubview(label)
        addSubview(overlay)
    }
    
    private func setupGestures() {
        let pan = UIPanGestureRecognizer()
        pan.addTarget(self,action: #selector(panned(_:)))
        addGestureRecognizer(pan)
    }
    
    @objc private func panned(_ g: UIPanGestureRecognizer) {
        switch g.state {
        case .began:
            self.initialAlpha = self.overlayAlpha
            self.initialLocation = g.location(in: self.window)
        case .changed:
            // get total translation
            self.totalTranslation = g.location(in: self.window).x - self.initialLocation.x
            
            // calculate alpha
            if self.initialAlpha == 1 {
                if totalTranslation > 0 {
                    self.overlayAlpha = 1 - totalTranslation / self.frame.width
                }
            }
            else {
                if totalTranslation < 0 {
                    self.overlayAlpha = -totalTranslation / self.frame.width
                }
            }
            
            // update
            self.overlay.alpha = self.overlayAlpha
            
        case .ended:
            // calculate
            self.overlayAlpha = 0
            
            if self.alpha == 0 {
                if totalTranslation < -self.frame.width / 2 || g.veLocity(in: self.window).x < -5 {
                    self.overlayAlpha = 1
                }
                else {
                    self.overlayAlpha = 0
                }
            }
            
            else {
                if totalTranslation > self.frame.width / 2 || g.veLocity(in: self.window).x > 5 {
                    self.overlayAlpha = 0
                }
                else {
                    self.overlayAlpha = 1
                }
            }
            
            // animate end
            let anim = UIViewPropertyAnimator(duration: 0.2,curve: .easeInOut)
            // anim.startAnimation() // <= LINE 1
            anim.addAnimations {
                self.overlay.alpha = self.overlayAlpha
            }
            anim.startAnimation() // <= LINE 2
            //
        default:
            break
        }
    }
}

问题

一旦在startAnimation()之前调用addAnimations(),拖动时亮度不再更新?

重现

取消注释 LINE 1 并注释 LINE 2 以查看此内容

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)