一段时间后,我回到了 iOS 开发,并在 SwiftUI 中从头开始重建我的 Objective-C 应用程序。
我想做的一件事是使用默认的编辑模式来允许列表中的条目(由 CloudKit 上的核心数据支持)在 NavigationLink 到详细视图和编辑视图之间切换。
主要方法似乎是通过检测编辑模式的 if 语句来处理它。Apple 文档在此开发人员页面上提供了此方法的以下代码片段:https ://developer.apple.com/documentation/swiftui/editmode
@Environment(\.editMode) private var editMode
@State private var name = "Maria Ruiz"
var body: some View {
Form {
if editMode?.wrappedValue.isEditing == true {
TextField("Name", text: $name)
} else {
Text(name)
}
}
.animation(nil, value: editMode?.wrappedValue)
.toolbar { // Assumes embedding this view in a NavigationView.
EditButton()
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这不起作用(我已按照假设将代码片段嵌入到 NavigationView 中)。这是 Xcode 13.4.1 中的错误吗?iOS 15.5?或者我做错了什么?
更新1:
根据 Asperi 的回答,我想出了以下通用视图来处理我的情况:
import SwiftUI
struct EditableRow: View {
#if os(iOS)
@Environment(\.editMode) private var editMode
#endif
@State var rowView: AnyView
@State var detailView: AnyView
@State var editView: AnyView
var body: some View {
NavigationLink{
if(editMode?.wrappedValue.isEditing == true){
editView
}
else{
detailView
}
}label: {
rowView
}
}
}
struct EditableRow_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
VStack {
EditButton()
EditableRow(rowView: AnyView(Text("Row")), detailView: AnyView(Text("Detail")), editView: AnyView(Text("Edit")))
}
}
}
Run Code Online (Sandbox Code Playgroud)
预览按预期工作,但这在我的真实应用程序中部分工作。当我实现此功能时,NavigationLink 在不处于编辑模式时可以工作,但在编辑模式时不会执行任何操作。我还尝试将整个 NavigationLink 放入 if 语句中,但结果相同。知道为什么这不起作用吗?
更新2:
当它位于列表中时会发生一些事情。当我将预览更改为这显示了我得到的行为:
struct EditableRow_Previews: PreviewProvider {
static var previews: some View {
NavigationView {
List {
EditableRow(rowView: AnyView(GroupRow(title: "Title", subTitle: "Subtitle", type: GroupType.personal)), detailView: AnyView(EntryList()), editView: AnyView(Text("Edit")))
}
.navigationBarItems(trailing:
HStack{
#if os(iOS)
EditButton()
#endif
}
)
}
}
}
Run Code Online (Sandbox Code Playgroud)
更新3:
找到这个答案:SwiftUI - EditMode 和PresentationMode Environment
这声称默认的 EditButton 已损坏,这似乎是真的。用自定义按钮替换默认按钮是可行的(请务必添加一个 withAnimation{} 块以从库存按钮获取所有行为。但它仍然不适用于我的 NavigationLink...
更新4:
好的,尝试将“isEditing”Bool 传递给上面的视图,而不是依赖于可用的环境变量。只要视图(在我的例子中是列表中的 ForEach)不处于“编辑模式”,无论此时发生什么都会破坏任何似乎的 NavigationLink,这都有效。
更新5:
基本上我的结论是,默认编辑模式旨在将“列表对象”作为一个整体进行编辑,从而可以移动和删除行。在这种模式下,Apple 认为编辑行本身并不是您想要做的事情。我可以看到这个观点。但是,如果您仍然想在编辑模式下从行启用 NavigationLink,这个答案应该会有所帮助: How to make SwiftUI NavigationLink work in edit mode?
Asperi 的答案确实涵盖了检测不起作用的原因。我确实发现,在手动设置编辑模式而不使用默认的 EditButton 时,编辑模式检测确实效果更好,请参阅上面的答案以了解详细信息。
它位于同一级别,因此环境不可见,因为它已针对子视图激活。
一个可能的解决方案是将依赖部分分离到独立视图中,例如
Form {
InternalView()
}
.toolbar {
EditButton()
}
Run Code Online (Sandbox Code Playgroud)
使用 Xcode 13.4 / iOS 15.5 进行测试
| 归档时间: |
|
| 查看次数: |
2601 次 |
| 最近记录: |