SwiftUI Form键盘收起后内容分两次下移的原因及解决方法
解决iOS16.0 SwiftUI Form键盘收起后内容分两次下移的问题
这是iOS16.0版本中Form组件的已知键盘适配bug,以下是几种可行的修复方案:
方案1:调整Form的键盘 dismiss 模式
给Form添加scrollDismissesKeyboard修饰符,强制使用交互式键盘收起行为,可修复分段下移问题:
var body: some View { Form { ForEach(0 ..< 40, id: \.self) { index in TextField("input\(index + 1)", text: $inputs[index]) } } .scrollDismissesKeyboard(.interactively) }
方案2:用ScrollView模拟Form样式(推荐)
既然ScrollView不存在该问题,我们可以用ScrollView结合基础组件模拟Form的视觉效果,完全规避Form的bug:
var body: some View { ScrollView { LazyVStack(spacing: 0) { ForEach(0 ..< 40, id: \.self) { index in TextField("input\(index + 1)", text: $inputs[index]) .padding(.horizontal, 16) .frame(height: 44) .background(Color(UIColor.systemBackground)) Divider() } } .background(Color(UIColor.systemGroupedBackground)) } }
该方案视觉上和原生Form几乎一致,同时保留ScrollView的正常键盘适配行为。
方案3:手动监听键盘状态调整布局
通过监听键盘的显示/隐藏通知,手动控制底部内边距的变化,替代Form的自动适配逻辑:
@State private var keyboardHeight: CGFloat = 0 var body: some View { Form { ForEach(0 ..< 40, id: \.self) { index in TextField("input\(index + 1)", text: $inputs[index]) } } .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillShowNotification)) { notification in guard let frame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect else { return } keyboardHeight = frame.height } .onReceive(NotificationCenter.default.publisher(for: UIResponder.keyboardWillHideNotification)) { _ in keyboardHeight = 0 } .padding(.bottom, keyboardHeight) .animation(.easeInOut(duration: 0.3), value: keyboardHeight) }
内容的提问来源于stack exchange,提问作者fanrui
相关产品推荐
相关产品推荐

