【问题标题】:SwiftUI List state not being persisted with contextmenuSwiftUI List 状态未与 contextmenu 保持一致
【发布时间】:2021-01-24 19:19:30
【问题描述】:

我有一个使用ForEach 列出数组的简单视图。列表中的每个项目都有一个上下文菜单,用于捕获对象并为该对象设置工作表。但是,它的初始执行不会设置状态,而后续执行会设置状态。

这是一个说明问题的简短程序:

struct MyTestView : View {
    var people = ["A", "B", "C", "D"]
    @State var collectedPerson = "Initial"
    @State var showingActionSheet = false
    var body : some View {
        List {
            ForEach(self.people, id: \.self) { person in
                Text(person)
                    .contextMenu {
                        Button("Edit \(person)") { // person is correct here
                            self.collectedPerson = person
                            self.showingActionSheet = true
                        }
                    }
                    .sheet(isPresented: self.$showingActionSheet) {
                        Text(self.collectedPerson) // State is not set the first time
                    }
            }
        }
    }
}

最初,屏幕加载“Initial”,这是不正确的:

如果我再次拉起上下文菜单,这一次,状态设置正确(假设我在 B 上拉起上下文菜单):

有谁知道为什么初始状态似乎没有设置?

【问题讨论】:

标签: swift swiftui


【解决方案1】:

这是您的代码快照的可能解决方案 - 使用 sheet(item:_) 修饰符

struct MyTestView : View {
    var people = ["A", "B", "C", "D"]
    @State var collectedPerson: String?

    var body : some View {
        List {
            ForEach(self.people, id: \.self) { person in
                Text(person)
                    .contextMenu {
                        Button("Edit \(person)") {
                            self.collectedPerson = person
                        }
                    }
                    // item required to be identifiable
                    .sheet(item: self.$collectedPerson) { person in
                        Text(person)
                    }
            }
        }
    }
}

extension String: Identifiable {
    public var id: String { self }
}

替代:使用分离视图在工作表中进行编辑并通过绑定注入状态属性

struct MyTestView : View {
    var people = ["A", "B", "C", "D"]
    @State var collectedPerson = "Initial"
    @State var showingActionSheet = false
    var body : some View {
        List {
            ForEach(self.people, id: \.self) { person in
                Text(person)
                    .contextMenu {
                        Button("Edit \(person)") { // person is correct here
                            self.collectedPerson = person
                            self.showingActionSheet = true
                        }
                    }
                    .sheet(isPresented: self.$showingActionSheet) {
                        MyTestEditView(person: self.$collectedPerson)
                    }
            }
        }
    }
}

struct MyTestEditView: View {
    @Binding var person: String
    var body: some View {
        Text(person)
    }
}

均已通过 Xcode 12.1 / iOS 14.1 测试和使用

【讨论】:

    猜你喜欢
    • 2020-03-21
    • 2023-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多