RxSwift使用RxCocoa绑定到动画

时间:2018-06-20 16:03:18

标签: swift rx-swift rx-cocoa

我有一个UIStepper值绑定到UILabel文本:

    unitsStepper.rx.value.asObservable()
        .map { Int($0).description }
        .bind(to: stepperCountLabel.rx.text)
        .disposed(by: rx.disposeBag)

每次更改标签时,我都希望对其进行动画处理,有替代此方法的更好方法吗?

    unitsStepper.rx.value.asObservable()
        .map { Int($0).description }.subscribe(onNext: { [weak self] value in
            guard let strongSelf = self else { return }
            UIView.animate(withDuration: 0.4, animations: {
                strongSelf.stepperCountLabel.text = value
                strongSelf.stepperCountLabel.transform = CGAffineTransform(scaleX: 1.5, y: 1.5)
            }, completion: { completed in
                strongSelf.stepperCountLabel.transform = CGAffineTransform.identity
            })

        }).disposed(by: rx.disposeBag)

1 个答案:

答案 0 :(得分:0)

我个人认为这没有什么不对。如果您希望它更具可读性,减少嵌套,则可以对其进行一些扩展。您的需求会有所不同,并且您不想用非常特定的内容来污染一般性的东西,但是看起来您有一些重复性的东西,一种脉动。

我需要类似的东西来进行表单验证,并编写了此代码(尽管您的实际动画更简单,但我认为我从多部分关键帧动画开始,但将其简化为来回移动)

extension UIView {

    func shake(totalDuration: TimeInterval, totalCycles: Int = 1) {

        let animationDuration = totalDuration / Double(totalCycles)
        let wiggle = CAKeyframeAnimation(keyPath: "transform.rotation.z")
        wiggle.values = [0.0, -0.04, 0.04, 0.0]
        wiggle.duration = animationDuration
        wiggle.repeatCount = Float(totalCycles)
        layer.add(wiggle, forKey: "wiggle")

        let vertical = CAKeyframeAnimation(keyPath: "transform.translation.y")
        vertical.values = [0.0, -2.0, 2.0, 0]
        vertical.duration = animationDuration
        vertical.repeatCount = Float(totalCycles)
        layer.add(vertical, forKey: "vertical")

        let horizontal = CAKeyframeAnimation(keyPath: "transform.translation.x")
        horizontal.values = [0.0, 2.0, -2.0, 0]
        horizontal.duration = animationDuration
        horizontal.repeatCount = Float(totalCycles)
        layer.add(horizontal, forKey: "horizontal")
    }

    func pulse(totalDuration: TimeInterval, ratio: CGFloat = 1.2) {

        UIView.animateKeyframes(
            withDuration: totalDuration,
            delay: 0,
            options: [],
            animations: {
                UIView.addKeyframe(
                    withRelativeStartTime: 0,
                    relativeDuration: 0.5,
                    animations: { [unowned self] in
                        self.transform = .init(scaleX: ratio, y: ratio)

                })
                UIView.addKeyframe(
                    withRelativeStartTime: 0.5,
                    relativeDuration: 0.5,
                    animations: { [unowned self] in
                        self.transform = .identity
                })
        }, completion: { completed in })
    }
}

然后,我编写了一个简单的带有条件和操作结束符的验证器结构,并将在表单更改/验证时浏览它们的列表。

但是回到您的问题,您的动画本身是最小的,如果是一次性的,则可以将其放在封闭的类中,如果是通用的,则可以将其添加为扩展,但作为一个扩展-关闭,它仍然可以(如果我正在阅读代码)