UIView动画展开时出现裁剪,修改约束后位置跳转如何解决?
iOS菜单展开动画裁剪、跳变问题修复方案
menuHeightConstraint 是UIView的高度约束
核心问题原因&修复步骤
- 裁剪问题根因:
menuView或其上级父视图开启了clipsToBounds属性,动画过程中logo放大、位移的速度快于menuView高度扩展的速度,超出当前视图bounds的内容会被自动裁剪。直接将menuView和所有父视图的clipsToBounds设为false即可解决。 - 位置跳变根因:你修改的约束涉及多个视图层级,仅在动画块内调用
menuView.layoutIfNeeded()无法触发所有关联约束的动画更新,同时缺少修改约束前的布局提交步骤,未结算的历史布局变更会导致跳变。
修正后可直接运行的代码
@IBAction func openMenu() { // 先提交之前未完成的布局变更,避免累计变更导致跳变 self.view.layoutIfNeeded() menuIsOpen.toggle() menuHeightConstraint.constant = menuIsOpen ? 180 : 55 logoHorizontalConstraint.constant = menuIsOpen ? 0 : -122 logoVerticalConstraint.constant = menuIsOpen ? 15 : 7 logoHeight.constant = menuIsOpen ? 75 : 40 logoWidth.constant = menuIsOpen ? 75 : 40 loginVertConstraint.constant = menuIsOpen ? 100 : 15 // label约束 let indicator = menuIsOpen ? UIImage(systemName: "arrow.up.circle.fill") : UIImage(systemName: "arrow.down.circle.fill") dropDownButtonImage.setImage(indicator, for: .normal) UIView.animate( withDuration: 0.5, delay: 0, options: .curveEaseIn, animations: { // 触发最外层控制器视图的全局布局更新,所有约束变更会同步执行动画 self.view.layoutIfNeeded() }, completion: nil) }
可选优化
如果修改后仍有轻微布局异常,可以检查logo相关约束的优先级,将宽高、位置约束的优先级调高到999,避免和系统默认生成的约束冲突。
内容的提问来源于stack exchange,提问作者Jef Janssen
相关产品推荐
相关产品推荐

