9

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

niklassaers
  • 8,480
  • 20
  • 99
  • 146
  • Did you try to add a frame(minWidth:0, minHeight:0) modifier on your VStack – Marc T. Oct 01 '19 at 06:45
  • I had tried setting an explicit frame on it. Setting ```.frame(minWidth: 0, minHeight: 0)``` on the VStack now, the result is still the same as in the screenshot above. If I set the VStack background color to red, I can see that the VStack is nicely sized, but the popover is still giant around it. (I updated the code and screenshot above to reflect that) – niklassaers Oct 01 '19 at 06:52
  • May I ask if you try it on macOS, iOS or iPadOS – Marc T. Oct 01 '19 at 06:54
  • This is on iPadOS (simulator), but macOS has the same behaviour – niklassaers Oct 01 '19 at 06:56
  • On macOS its definitely working correct but on iPadOS not. Looks like a bug or its intended behaviour defined by Apple. I did not find any way to change it. – Marc T. Oct 01 '19 at 16:59
  • @MarcT. What did you do to get it working correctly on macOS? With the code above, on Xcode 11.0, the popover does not follow the content frame, but is giant around it still (screenshot appended to the post) – niklassaers Oct 04 '19 at 20:30
  • Have you considered using a `Menu`? This tiny popover looks like it's supposed to be a menu instead. – bio Jun 12 '22 at 18:42

2 Answers2

4

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

Marc T.
  • 5,090
  • 1
  • 23
  • 40
  • That is so interesting! I've made sure I'm no longer on the Catalina beta, I've updated to Xcode 11.1, and copy-pasted the code you provided into Xcode, yet I cannot get the same result. Would you mind sharing your project so I can see if there are other differences? Because what you show there is exactly what I want to achieve – niklassaers Oct 09 '19 at 11:40
  • 1
    Sorry for the delay. Added a sample project link. – Marc T. Oct 12 '19 at 08:42
  • Thanks, for those reading along, you should replace the Hello World in Content View with the contents of the struct above. And indeed, you get the result Marc showed. So it works as a Mac app, the difference being that I had made it as a macOS Catalyst app – niklassaers Oct 25 '19 at 09:46
  • 3
    You example works for me as well, but did you try this with a `List`? In this case, the popover is really small and doesn't fit to the `List`. – Lupurus Mar 29 '20 at 14:26
  • 1
    I am getting the same behaviour @Lupurus. I have a popover attached to a list and it now defaults to a tiny size, not the size of the content in the popover. Frame seems to now need explicit sizing. Likely a bug, wasnt that way before iPadOS 13.4 – tarasis Apr 01 '20 at 11:55
  • 2
    @Lupurus I had the same experience with trying to use `List`, but found that simulating a `List` with a `VStack` inside a `ScrollView` and using `Divider` views worked for my case. Gist at https://gist.github.com/mluton/c70bac24d6d01db06c93b8d0857dd0f7 – Michael Luton Sep 13 '20 at 18:15
2

It looks like this has been fixed in iOS 13.4 / Xcode 11.4 Beta. The popover will size to whatever it's contents are now.

choxi
  • 455
  • 4
  • 18
  • Can confirm. Just be aware that it behaves differently if you size the app differently, like if you put the app into split screen on the iPad then the popover behaves like a sheet and the content is in the middle. – Helam Mar 10 '20 at 17:04