iOS 15模拟器中SwiftUI滚动出现显示异常bug,寻求可行解决方案
问题根因
这是Xcode 13使用iOS 15 SDK编译SwiftUI项目的已知Bug,由你代码中未指定触发条件的隐式动画声明触发,嵌套滚动容器(ScrollView嵌套LazyVStack/LazyHStack)会因为无限制的动画重计算出现布局偏移,部分版本的Xcode 13配套模拟器还会出现全局渲染异常,连带主界面显示截断。
解决步骤
修正动画声明
SwiftUI从iOS 15开始对隐式动画的作用范围做了调整,直接使用.animation(.default)不指定触发值的写法会导致所有布局变化(包括滚动、系统手势触发的布局重排)都被加入动画计算,最终出现布局异常。你代码中按钮无需要动画响应的状态变化,可以直接删除.animation(.default)这行;如果需要特定状态变化时触发动画,修改为带值绑定的写法:.animation(.default, value: 你要监听的状态变量)修复模拟器全局渲染异常
如果调整代码后模拟器仍然出现主屏幕也被截断的问题,执行以下操作重置模拟器:- 完全退出Xcode和模拟器应用
- 打开终端执行命令:
xcrun simctl erase all - 重启Mac后重新打开Xcode运行项目即可
安全区域兼容补充
若需要兼容iOS 14与iOS 15不同的安全区域计算逻辑,可在最外层ScrollView添加明确的安全区域声明:.ignoresSafeArea(.container, edges: .top)
修正后可正常运行的代码示例
// // ContentView.swift // ForElTomato // // Created by Ran on 9/30/21. // import SwiftUI struct ContentView: View { let colors:[Color] = [Color.red, Color.blue, Color.green] let names:[String] = ["El", "Tomato", "The Best"] var body: some View { ScrollView(.vertical, showsIndicators: true) { LazyVStack(alignment: .center, spacing: 10, pinnedViews: []) { ForEach(colors, id: \.self) { clr in ScrollView(.horizontal, showsIndicators: false) { LazyHStack(alignment: .center, spacing: 10, pinnedViews: []) { ForEach(names, id: \.self) { name in Button(action: { //nothing }) { HStack { Text(name) }.padding(10) } .foregroundColor(.black) .background(clr) // 移除无绑定的动画声明,或替换为带value的版本 } } }) }.padding(.leading) } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
内容的提问来源于stack exchange,提问作者jonmecer
相关产品推荐
相关产品推荐

