代码之家  ›  专栏  ›  技术社区  ›  Stefan

uiviewPropertyImator自动布局完成问题

  •  0
  • Stefan  · 技术社区  · 6 年前

    我正在使用UIViewPropertyAnimator运行一个数组交互动画,我遇到的一个问题是,每当我反转动画时,我就不能再向前运行动画。

    我使用三个函数来处理动画与一个泛手势识别器。

    private var runningAnimations = [UIViewPropertyAnimator]()
    
    private func startInteractiveTransition(gestureRecognizer: UIPanGestureRecognizer, state: ForegroundState, duration: TimeInterval) {
    
        if runningAnimations.isEmpty {
            animateTransitionIfNeeded(gestureRecognizer: gestureRecognizer, state: state, duration: duration)
        }
    
        for animator in runningAnimations {
            animator.pauseAnimation()
            animationProgressWhenInterrupted = animator.fractionComplete
        }
    }
    
    private func animateTransitionIfNeeded(gestureRecognizer: UIPanGestureRecognizer, state: ForegroundState, duration: TimeInterval) {
    
        guard runningAnimations.isEmpty else {
            return
        }
    
        let frameAnimator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) {
    
            switch state {
            case .expanded:
                // change frame
            case .collapsed:
                // change frame
            }
        }
    
        frameAnimator.isReversed = false
    
        frameAnimator.addCompletion { _ in
            print("remove all animations")
            self.runningAnimations.removeAll()
        }
    
        self.runningAnimations.append(frameAnimator)
    
        for animator in runningAnimations {
            animator.startAnimation()
        }
    }
    
    private func updateInteractiveTransition(gestureRecognizer: UIPanGestureRecognizer, fractionComplete: CGFloat) {
    
        if runningAnimations.isEmpty {
            print("empty")
        }
                for animator in runningAnimations {
            animator.fractionComplete = fractionComplete + animationProgressWhenInterrupted
        }
    }
    

    我注意到的是,在我反转动画并调用animateTransitionIfNeeded之后,frameAnimator会附加到运行动画中,但是当我在紧接着调用updateInteractiveTransition并选中running animations之后,它是空的。

    所以我相信这可能与swift处理内存的方式有关,也可能与uiviewanimating完成动画的方式有关。

    有什么建议吗?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Stefan    6 年前

    我逐渐意识到,我的问题在于uiviewpropertyanimator如何在反转时处理布局约束。 我在网上或官方文件中找不到太多细节,但我确实发现这有很大帮助。

    Animator只是将视图设置为新帧的动画但是,无论是否反转动画制作程序,新约束仍保持不变。因此,在动画师完成后,如果稍后的autolayout再次布局视图,我希望视图进入由当前活动约束设置的位置简单地说:动画师动画帧的变化,但不是约束本身这意味着反转animator将反转帧,但它不会反转约束-一旦autolayout执行另一个布局循环,它们将再次应用。

    像平常一样,你设置约束并调用 view.layoutIfNeeded()

    animator = UIViewPropertyAnimator(duration: duration, dampingRatio: 1) {
            [unowned self] in
    
            switch state {
            case .expanded:
                self.constraintA.isActive = false
                self.constraintB.isActive = true
                self.view.layoutIfNeeded()
            case .collapsed:
                self.constraintB.isActive = false
                self.constraintA.isActive = true
                self.view.layoutIfNeeded()
            }
    }
    

    现在,由于我们的动画师能够反转,我们添加了一个完成处理程序,以确保通过使用完成位置在完成时激活正确的约束。

    animator.addCompletion {  [weak self] (position) in
    
            if position == .start {
                switch state {
                case .collapsed:
                    self?.constraintA.isActive = false
                    self?.constraintB.isActive = true
                    self?.view.layoutIfNeeded()
                case .expanded:
                    self?.constraintA.isActive = false
                    self?.constraintB.isActive = true
                    self?.view.layoutIfNeeded()
                }
            }
    }
    
        2
  •  0
  •   Silo    5 年前

    animator操作视图的可设置动画的属性,例如 框架 , 中心 我是说, 阿尔法 ,和 变换属性 ,从提供的块创建所需的动画。

    这是文档的关键部分。 可以正确设置动画: 帧、中心、alpha和变换,因此无法正确设置NSConstraints的动画。

    您应该在 addAnimations