将 .popover 附加到列表中的 ForEach 或部分会创建多个弹出窗口

mil*_*man 5 ios swiftui

我有List多个Section,每个部分都有不同类型的数据。对于每个部分,我想单击一个项目来呈现一个弹出窗口。

问题是,如果我将 附加.popoverSectionForEach,那么.popover似乎会应用于列表中的每个条目。因此,即使只单击一个项目,也会为每个项目创建弹出窗口。

示例代码如下。我无法将 附加.popover到 ,List因为就我而言,有 2 种不同样式的.popover,并且每个视图只能附加一个.popover

struct Item: Identifiable {
    var id = UUID()
    var title: String
}

var items: [Item] = [
    Item(title: "Item 1"),
    Item(title: "Item 2"),
    Item(title: "Item 3"),
]

struct PopoverView: View {
    @State var item: Item
    
    var body: some View {
        print("new PopoverView")
        return Text("View for \(item.title)")
    }
}

struct ContentView: View {
    @State var currentItem: Item?
    
    var body: some View {
        List {
            Section(header: Text("Items")) {
                ForEach(items) { item in
                    Button(action: { currentItem = item }) {
                        Text("\(item.title)")
                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我目前提出的最佳解决方案是将弹出窗口附加到每个弹出窗口Button,然后只允许一个基于的弹出窗口currentItem

                    Button(action: { currentItem = item }) {
                        Text("\(item.title)")
                    }
                    .popover(isPresented: .init(get: { currentItem == item },
                                                set: { $0 ? (currentItem = item) : (currentItem = nil) })) {
                        PopoverView(item: item)
                    }
Run Code Online (Sandbox Code Playgroud)

有更好的方法来做到这一点吗?

解决这个问题的奖励点:当我使用我的黑客时,向下拖动动作似乎出现故障,并且视图再次从顶部出现。不知道这有什么关系。

clu*_*der 6

您始终可以为您的项目创建单独的视图。

struct MyGreatItemView: View {
    @State var isPresented = false
    var item: Item
   
    var body: some View {

          Button(action: { isPresented = true }) {
                        Text("\(item.title)")
                    }
           .popover(isPresented: $isPresented) {
                        PopoverView(item: item)
                    }

    }
}
Run Code Online (Sandbox Code Playgroud)

并将其实现到ContentView:

struct ContentView: View {  
    var body: some View {
        List {
            Section(header: Text("Items")) {
                ForEach(items) { item in
                   MyGreatItemView(item: item)
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Ene*_*man 2

尝试访问类似sheetpopoverin 的组件ForEach会导致问题。我也遇到过你提到的故障,但下面(带工作表)按预期工作;

List {
    Section(header: Text("Items")) {
        ForEach(items) { item in
            Button(action: { currentItem = item }) {
                Text("\(item.title)")
            }
        }
    }
}
.sheet(item: $currentItem, content: PopoverView.init)
Run Code Online (Sandbox Code Playgroud)