当启用多个部分按钮时,弹出窗口功能会中断,但当仅限于一个按钮时,它会按预期工作。
struct ContentView: View {
var items = ["Note 1", "Note 2", "Note 3"]
@State private var showPopover = false
var body: some View {
List {
Section {
ForEach(items, id: \.self) { item in
VStack {
Text(item)
.padding()
Button(action: {
showPopover.toggle()
}, label: {
Text("Notes")
})
.popover(isPresented: $showPopover) {
Text(item)
.padding()
.foregroundStyle(Color.red)
.font(.body)
.lineLimit(nil)
.presentationCompactAdaptation(.popover)
}
}
.frame(maxWidth: .infinity)
}
}
}
}
}
虽然每个部分都旨在通过弹出窗口显示注释,但 SwiftUI 似乎在跨多个部分处理此功能方面存在限制。
您只需使用一个
Bool
状态即可控制所有弹出窗口。当 showPopover
设置为 true 时,all 弹出窗口将尝试显示,但会失败,因为同时显示的弹出窗口不能超过一个。
您可以使用
[Bool]
或 [String: Bool]
作为状态,这样您就可以存储多个 Bool
来表示是否显示弹出窗口,每个按钮一个。但是,将整个按钮提取到其自己的视图中并将 Bool
放入该视图中会更方便。
struct PopoverButton: View {
let item: String
// move showPopover here
@State private var showPopover = false
var body: some View {
Button(action: {
showPopover.toggle()
}, label: {
Text("Notes")
})
.popover(isPresented: $showPopover) {
Text(item)
.padding()
.foregroundStyle(Color.red)
.font(.body)
.lineLimit(nil)
.presentationCompactAdaptation(.popover)
}
}
}
现在,如果您将
PopoverButton
放入 ForEach
中,每个按钮都会有一个单独的状态。
List {
Section {
ForEach(items, id: \.self) { item in
VStack {
Text(item)
.padding()
PopoverButton(item: item)
}
.frame(maxWidth: .infinity)
}
}
}
.buttonStyle(.borderless)