SwiftUI列表底部行Sheet调用后按回车自动消失问题求助
解决列表底部行Sheet因TextField操作自动消失的问题
问题复现场景
- 包含100条项目的列表,每行附带Menu View
- 滚动至第99行:点击编辑按钮唤起Menu,再次点击编辑打开Sheet;点击TextField唤起键盘并按回车,Sheet自动消失
- 第97行:仅点击TextField就触发Sheet消失
- 模拟器与真机均能稳定复现
- 已尝试无效方案:
- 禁用Interactive修饰符
- 使用接收item参数的sheet修饰符变体
- 将sheet替换为full screen cover
- 使用FocusState属性包装器及相关修饰符
核心原因
问题根源在于Sheet绑定到了List行内的MenuView。List会复用行视图,当键盘弹出导致布局变化时,底部行可能被移出视图层级,MenuView的@State变量showingSheet会被重置为false,进而触发Sheet自动关闭。
解决方案
将Sheet的展示逻辑移至父视图(ContentView),通过统一的状态变量管理当前编辑的项目,避免Sheet与List行的生命周期绑定。
修正后代码
import SwiftUI struct ContentView: View { // 用可选值跟踪当前选中的编辑项 @State private var selectedItem: Int? = nil var body: some View { List(0..<100) { number in HStack { Text("\(number)") Spacer() // 传递编辑回调给MenuView MenuView(onEditTap: { selectedItem = number }) } } // 在父视图层级绑定Sheet,基于selectedItem控制展示 .sheet(item: $selectedItem) { _ in SheetView() } } } struct MenuView: View { let onEditTap: () -> Void var body: some View { Menu { Button("Edit") { onEditTap() } } label: { Label("Edit", systemImage: "pencil") } } } struct SheetView: View { @Environment(\.dismiss) private var dismiss @State private var text = "" var body: some View { NavigationStack { ScrollView { TextField("Name", text: $text) .padding() .textFieldStyle(.roundedBorder) } .navigationTitle("编辑项目") .toolbar { Button("完成") { dismiss() } } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
说明
- 父视图ContentView维护
selectedItem状态,统一管理Sheet的展示与隐藏 - MenuView不再持有Sheet状态,仅通过回调通知父视图触发编辑
- 使用
sheet(item:)绑定可选值,确保Sheet的生命周期与父视图绑定,不受List行复用影响
内容的提问来源于stack exchange,提问作者User95797654974
相关产品推荐
相关产品推荐

