Search code examples
swiftxcodepopoverswiftui

SwiftUI: Sizing a popover to fit


I've got a little popover sample in which a button triggers a popover. The popover only contains a little bit of UI, two buttons in this case, but it still takes up a lot of space instead of wrapping neatly around the content like I'm used to from UIKit. How do I make the popover fit to the size of the content?

Screenshot from the iPad simulator and code below:

Screenshot of the button with the popover open

struct ContentView: View {

    @State private var showingPopupA = false

    var body: some View {
        HStack {
            Button(action: {
                self.showingPopupA.toggle()
            }, label: {
                Text("Button")
            }).popover(isPresented: self.$showingPopupA) {
                VStack {
                    Button(action: {
                        // Do something
                        self.showingPopupA = false
                    }) {
                        Text("Option A")
                    }
                    Button(action: {
                        // Do something
                        self.showingPopupA = false
                    }) {
                        Text("Option B")
                    }
                }.background(Color.red)
            }
        }
    }
}

Screenshot from macOS: macOS screenshot built with Xcode 11.0


Solution

  • On macOS the code below will look like this:

    enter image description here

    struct PopoverExample: View {
    
        @State private var showingPopupA:Bool = false 
        var body: some View {
            HStack {
                Button(action: {
                    self.showingPopupA.toggle()
                }, label: {
                    Text("Button")
                }).popover(isPresented: self.$showingPopupA) {
                    VStack {
                        Button(action: {
                            // Do something
                            self.showingPopupA = false
                        }) {
                            Text("Option A")
                        }
                        Button(action: {
                            // Do something
                            self.showingPopupA = false
                        }) {
                            Text("Option B")
                        }
                    }.background(Color.red)
                }
            }
            .frame( maxWidth: .infinity, maxHeight: .infinity)
        }
    }
    

    Project link