我有这个代码:
import SwiftUI
struct ContentView: View {
@State var show = false
var tools = [Tool("document.on.document"), Tool("document.on.clipboard")]
var body: some View {
HStack{
HStack {
ForEach(tools, id:\.id) { tool in
Button(action: {
print("toggle")
show.toggle()
}, label: {
Image(systemName:tool.name)
.imageScale(.large)
.foregroundStyle(.black.gradient)
.font(.system(size: 30))
})
.contentShape(Rectangle())
.popover(isPresented: $show, arrowEdge: .top) {
Color.red
.frame(width:400, height:400)
.onAppear{
print("popover show")
}
}
}
}
.padding()
}
.background(
RoundedRectangle(cornerSize: CGSize(width: 50,height: 50))
.fill(.red.opacity(0.5).gradient))
.padding()
}
}
#Preview {
ContentView()
}
struct Tool: Identifiable, Equatable {
let id = UUID()
let name:String
init(_ name: String) {
self.name = name
}
}
弹出窗口不显示。我什么都做了。
这是为什么?
您正在使用单个
show
状态来控制所有弹出窗口!无法同时显示多个弹出窗口,因此会显示注释。
技术上可以将
show
的类型更改为[Bool]
,并将$show[0]
、$show[1]
等传递给isPresented
,但查找tool
的索引之类的东西会很不方便那个。
如果父视图不需要确切知道显示哪些弹出窗口,则应该将按钮提取到单独的视图中:
struct ToolButton: View {
@State private var show = false
let tool: Tool
// pass anything else you need here...
var body: some View {
Button(action: {
print("toggle")
show.toggle()
}, label: {
Image(systemName: tool.name)
.imageScale(.large)
.foregroundStyle(.black.gradient)
.font(.system(size: 30))
})
.contentShape(Rectangle())
.popover(isPresented: $show, arrowEdge: .top) {
Color.red
.frame(width:400, height:400)
.presentationCompactAdaptation(.popover) // if you also want a popover on iPhones
.onAppear{
print("popover show")
}
}
}
}
由于
@State
位于 ToolButton
中,因此会有与 ToolButton
一样多的状态,这意味着控制每个弹出框的一个状态。
ForEach(tools) { tool in
ToolButton(tool: tool)
}