Home > Enterprise >  I want to use multiple popovers with buttons in the Swift UI
I want to use multiple popovers with buttons in the Swift UI

Time:06-04

When using Popover with a button in SwiftUI, I want to popover with multiple buttons as shown below, but as it is, only the upper button I can't get a popover. What if you want to popover both separately?

struct MySelection: Identifiable {
        let id = UUID()
        var text = ""
    }
    
    struct PopoverTest: View {
        @State var selected: MySelection?
        
        var body: some View {
            VStack (spacing: 88) {
                // First Button
                Button(action: {
                    selected = MySelection(text: "Popover1")
                }, label: {
                    Image(systemName: "stopwatch")
                })
                // Second Button
                Button(action: {
                    selected = MySelection(text: "Popover2")
                }, label: {
                    Image(systemName: "globe")
                })
            }
            .buttonStyle(.plain)
            .popover(item: $selected) { selection in
                Text(selection.text).font(.largeTitle)
            }
        }
        
    }

CodePudding user response:

In this case it seems you have to introduce 2 selected vars. The optional selected can hand over different values to the popover, but if it is triggered from different subviews, SwiftUI doesn't know where to anchor the popover to.

struct ContentView: View {
    @State var selected1: MySelection?
    @State var selected2: MySelection?

    var body: some View {
        VStack (spacing: 88) {
            
            // First Button
            Button(action: {
                selected1 = MySelection(text: "Popover1")
            }, label: {
                Image(systemName: "stopwatch")
            })
            .popover(item: $selected1) { selection in
                Text(selection.text).font(.largeTitle)
            }
            
            // Second Button
            Button(action: {
                selected2 = MySelection(text: "Popover2")
            }, label: {
                Image(systemName: "globe")
            })
            .popover(item: $selected2) { selection in
                Text(selection.text).font(.largeTitle)
            }
        }
        .buttonStyle(.plain)
    }
}

CodePudding user response:

Thinking it over, the better way might be to create a custom "button with popover" view that can be used anywhere:

struct ContentView: View {

    var body: some View {
        VStack (spacing: 88) {
            
            // First Button
            ButtonWithPopover(image: "stopwatch",
                              item: MySelection(text: "Popover1"))
            
            // Second Button
            ButtonWithPopover(image: "globe",
                              item: MySelection(text: "Popover2"))
        }
        .buttonStyle(.plain)
    }
}


struct ButtonWithPopover: View {
    
    let image: String
    let item: MySelection
    
    @State var selected: MySelection?
    
    var body: some View {
        Button(action: {
            selected = item
        }, label: {
            Image(systemName: image)
        })
        .popover(item: $selected) { selection in
            Text(selection.text).font(.largeTitle)
        }
    }
}
  • Related