【发布时间】:2023-01-23 08:07:36
【问题描述】:
一段时间后我又回到了 iOS 开发,我正在 SwiftUI 中从头开始重建我的 Objective-C 应用程序。
我想做的一件事是使用默认的编辑模式允许列表中的条目(由 CloudKit 上的核心数据支持)在导航链接到详细视图和编辑视图之间切换。
主要方法似乎是通过检测编辑模式的 if 语句来处理它。 Apple 文档在此开发人员页面上为这种方法提供了以下 sn-p: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()
}
}
但是,这不起作用(我已经将 sn-p 嵌入到 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")))
}
}
}
预览按预期工作,但这在我的真实应用程序中部分有效。当我实现这个时,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
}
)
}
}
}
更新3:
找到这个答案:SwiftUI - EditMode and PresentationMode Environment
这声称默认的 EditButton 已损坏,这似乎是真的。用自定义按钮替换默认按钮是可行的(一定要添加 withAnimation{} 块以从库存按钮获取所有行为。 但它仍然不适用于我的 NavigationLink ...
更新4:
好的,尝试将“isEditing”Bool 传递给上面的视图,而不是依赖于可用的环境变量。只要 View(在我的例子中是 List 中的 ForEach)不处于“编辑模式”,无论此时发生什么都会破坏任何 NavigationLink,这都会起作用。
更新5:
基本上我的结论是默认的编辑模式是为了编辑“列表对象”作为一个整体来移动和删除行。在这种模式下,Apple 认为自己编辑行不是您想要做的事情。我可以看到这个观点。 但是,如果您仍想在编辑模式下的一行中启用 NavigationLink,则此答案应该有所帮助: How to make SwiftUI NavigationLink work in edit mode?
Asperi 的回答确实涵盖了为什么检测不起作用。我确实发现当手动设置编辑模式而不使用默认的 EditButton 时,编辑模式检测确实工作得更好,有关详细信息,请参见上面的答案。
【问题讨论】:
-
@Asperi 给出了一个很好的解决方法。但是因为它与文档不符,我已经向 Apple 提交了错误报告:FB10429307