Xcode13/iOS15下SwiftUI被NavigationView包裹的动画圆跳转异常
原因说明
该问题是iOS 15+ 对NavigationView布局生命周期的调整导致的:
iOS 15之前NavigationView的根视图布局会在onAppear回调触发前完成计算,而iOS 15+中根视图会先按左上角坐标完成初始布局,再在后续渲染周期调整到最终位置。你在onAppear中触发的全局动画会把这次位置调整也纳入动画范围,因此会出现圆形从左上角飞到屏幕中央、连带父视图一起动画的异常。
修正后的代码
#if DEBUG struct AnimatedCircle_Previews: PreviewProvider { static var previews: some View { AnimatedCircle() } } #endif struct AnimatedCircle: View { @State var scale: CGFloat = 1 var body: some View { NavigationView { Circle() .frame(width: 200, height: 200) .scaleEffect(scale) // 仅当scale属性变化时触发动画 .animation(.easeInOut(duration: 1).repeatForever(autoreverses: true), value: scale) // 撑满NavigationView可用空间,内容默认居中,提前确定布局位置 .frame(maxWidth: .infinity, maxHeight: .infinity) .onAppear { // 直接修改状态,动画由上层修饰符控制 scale = 0.5 } } } }
核心修改点
- 给圆形外层添加
frame(maxWidth: .infinity, maxHeight: .infinity)修饰符,让根视图直接撑满NavigationView的可用空间,圆形默认居中,不存在后续的位置调整逻辑,从根源避免位置变化被纳入动画。 - 用iOS 15+推荐的
animation(_:value:)修饰符替代全局withAnimation,明确指定动画仅响应scale属性的变化,布局类属性的变动不会被捕获进动画,也不会影响父视图和同级视图的正常展示。
内容的提问来源于stack exchange,提问作者Niklas
相关产品推荐
相关产品推荐

