iOS15下未嵌套NavigationView时SwiftUI List的EditButton失效问题
问题复现
场景:项目中配合使用SwiftUI的EditButton()与List()组件,iOS15系统上该功能突然失效。未在外层使用NavigationView包裹,此前实现可正常运行,且当前无法选择使用NavigationView作为解决方案。
问题代码:
struct Test: View { @State private var items: [String] = ["Item1", "Item2", "Item3"] // mock / demo var body: some View { VTile(padding: 0) { HStack { Text("Title") Spacer() } .overlay(EditButton()) List { ForEach(items, id: \.self) { item in HStack { Text(item) Spacer() } } .onDelete(perform: delete) .onMove(perform: move) } .listStyle(PlainListStyle()) } } func move(from source: IndexSet, to destination: Int) { // ... } func delete(at offsets: IndexSet) { // ... } }
问题现象:
- 尝试使用
@Environment(\.editMode) var editMode监听编辑模式无效果 - 无论环境变量中的编辑模式状态如何,List右侧始终不会显示可拖动排序的“移动”条
- 补充现象:刷新(关闭后重新打开包含该List的视图)后,List就会进入编辑模式
疑问
- 上述情况是否为iOS15的系统Bug?
- 有没有无需使用NavigationView的规范实现方案可以解决该问题?
临时解决方案
目前摸索出的临时方案可解决问题,但部分场景下可能存在副作用。根据观察,刷新List即可使其正确进入编辑模式,因此可以在编辑模式切换时(比如监听editMode环境变量变化)手动触发List重渲染即可实现预期效果。要让任意SwiftUI元素重渲染,只需要为其绑定唯一id,修改id即可强制视图重渲染。
实现代码:
@Environment(\.editMode) var editMode @State private var updateId: UUID = UUID() // ... List { /* ... */ }.id(updateId) // ... func toggleEditMode() { // toggle edit mode editMode.toggle() // force update updateId = UUID() // <------- update the list }
内容的提问来源于stack exchange,提问作者Leo
相关产品推荐
相关产品推荐

