Search code examples
swiftswiftuiio

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


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)
            }
        }
        
    }

Solution

  • 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)
            }
        }
    }