iOS16 SwiftUI弹窗关闭后键盘引发布局异常Bug及临时方案求助
iOS16 SwiftUI Sheet关闭后页面布局未同步更新的临时修复方案
在iOS16系统中使用SwiftUI开发时,会遇到这样的Bug:当Sheet弹窗内的TextField唤起键盘后,关闭弹窗时键盘虽正常消失,但原页面布局并未同步更新,出现布局错乱。
复现代码
struct Test: View { @State var isPresented: Bool = false @State var text: String = "" var body: some View { VStack{ Button { isPresented.toggle() } label: { Text("PRESENT") } } .sheet(isPresented: $isPresented) { ZStack { Color.red VStack{ TextField("Test", text: $text) .frame(height: 50, alignment: .center) Spacer() Rectangle() .fill(Color.blue) .frame(width:300, height: 50) } } } } }
临时解决方案
以下是两种可行的临时修复方式,可用于Apple官方修复该Bug前过渡:
方案1:通过id强制视图重建
在主视图中添加一个触发刷新的状态变量,在Sheet关闭的onDismiss回调中切换该变量,并绑定到主视图的id上,通过id变化强制视图重建,同步布局:
struct Test: View { @State var isPresented: Bool = false @State var text: String = "" @State private var refreshFlag = false // 触发刷新的标记变量 var body: some View { VStack{ Button { isPresented.toggle() } label: { Text("PRESENT") } } .sheet(isPresented: $isPresented, onDismiss: { // 关闭Sheet时切换标记,触发视图重建 refreshFlag.toggle() }) { ZStack { Color.red VStack{ TextField("Test", text: $text) .frame(height: 50, alignment: .center) Spacer() Rectangle() .fill(Color.blue) .frame(width:300, height: 50) } } } .id(refreshFlag) // 绑定id,标记变化时重建视图 } }
方案2:延迟触发布局更新
利用DispatchQueue在Sheet关闭后延迟一小段时间,通过无意义的布局参数变化触发主视图更新,适合不想重建整个视图的场景:
struct Test: View { @State var isPresented: Bool = false @State var text: String = "" @State private var layoutTrigger = false var body: some View { VStack{ Button { isPresented.toggle() } label: { Text("PRESENT") } } .padding(layoutTrigger ? 0 : 0) // 用无意义的padding变化触发布局 .sheet(isPresented: $isPresented, onDismiss: { DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) { layoutTrigger.toggle() DispatchQueue.main.asyncAfter(deadline: .now() + 0.01) { layoutTrigger.toggle() } } }) { ZStack { Color.red VStack{ TextField("Test", text: $text) .frame(height: 50, alignment: .center) Spacer() Rectangle() .fill(Color.blue) .frame(width:300, height: 50) } } } } }
说明
以上方案均为临时 workaround,待Apple官方修复iOS16的该SwiftUI Bug后,可移除相关代码恢复原实现。
内容的提问来源于stack exchange,提问作者Igor Ševtšenko
相关产品推荐
相关产品推荐

