使用UIView.animate做约束动画时为何出现延迟?
约束动画滞后问题:UIView.animate操作drawerHeight约束时底部边缘延迟
我最近在做抽屉视图的动画时踩了个坑:用UIView.animate修改drawerHeight约束的constant值时,抽屉底部的可见边缘总是明显滞后于主体动画。先贴一下我最开始的代码:
drawerHeight?.constant = newHeight UIView.animate(withDuration: 0.35, delay: 0, usingSpringWithDamping: 0.65, initialSpringVelocity: 2, options: .allowUserInteraction, animations: { self.superview?.layoutIfNeeded() })
观察动画过程,抽屉主体在平滑移动,但底部边缘却跟不上节奏,显得卡顿拖沓。折腾了一会儿后,我终于找到问题根源,也搞定了修复方法,分享给遇到同样问题的开发者:
问题出在哪:布局更新的范围太小
最开始我只在动画块里调用了self.superview?.layoutIfNeeded(),也就是只让抽屉的直接父视图更新布局。但如果这个父视图还嵌套在其他视图层级里(比如scrollView、容器视图),更高层级的视图布局并没有被同步触发动画,导致抽屉边缘因为依赖上层视图的布局更新,出现了视觉上的滞后。
快速修复方案
只需要把动画块里的布局更新对象换成覆盖整个动画视图树的顶层视图就行:
方案1:在ViewController中直接调用根视图的layoutIfNeeded
drawerHeight?.constant = newHeight UIView.animate(withDuration: 0.35, delay: 0, usingSpringWithDamping: 0.65, initialSpringVelocity: 2, options: .allowUserInteraction, animations: { self.view.layoutIfNeeded() })
方案2:在视图类内部全局触发布局更新
drawerHeight?.constant = newHeight UIView.animate(withDuration: 0.35, delay: 0, usingSpringWithDamping: 0.65, initialSpringVelocity: 2, options: .allowUserInteraction, animations: { UIApplication.shared.keyWindow?.layoutIfNeeded() })
修改后整个视图树的布局会在动画过程中同步更新,抽屉底部边缘就会和主体动画完全对齐,再也没有滞后问题了。
内容的提问来源于stack exchange,提问作者George
相关产品推荐
相关产品推荐

