Difference between 2 adaptivePresentationStyle methods of the UIPopoverPresentationControllerDelegate protocol

303 Views Asked by At

I am using a popover view controller where I don't want the popover to cover the full screen (iOS 13). I was trying to use:

func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
        return .none
}

The method was being called but the popover displayed was always full screen, even though a smaller preferred content size was being specified. After a lot of time trying many different things I found that there is another method which has 2 parameters and used it:

func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
        return .none
}

Using this method makes the popover screen be the specified size. Anybody have an idea why the second one would work and the first one won't. I have a couple other apps in which I am using the first one with no issues, what gives?!!

2

There are 2 best solutions below

1
On

Due to the documentation: from iOS 8.3 we should use

adaptivePresentationStyle(for:traitCollection:)

to handle all trait changes. Where

UITraitCollection - The iOS interface environment, defined by traits such as horizontal and vertical size class, display scale, and user interface idiom.

If we do not implement this method in the delegate, UIKit calls the

adaptivePresentationStyle(for:)

method instead.

So I guess in your app you try to create an adaptive interface and access specific trait values using the UITraitCollection horizontalSizeClass, verticalSizeClass, displayScale, and userInterfaceIdiom properties. That is why you should implement adaptivePresentationStyle(for:traitCollection:).

1
On

To second this answer, I was using:

func adaptivePresentationStyle(for controller: UIPresentationController) -> UIModalPresentationStyle {
    return .none
}

and was getting popovers correctly on the iPad (iPadOS 16) but full screen on the iPhone (iOS 16.2)

I then changed to:

func adaptivePresentationStyle(for controller: UIPresentationController, traitCollection: UITraitCollection) -> UIModalPresentationStyle {
    return .none
}

And get popovers on both platforms.

It isn't clear from the documentation why this works as it says that if you don't implement adaptivePresentationStyle(for:traitCollection:) in your delegate, it just defaults to calling adaptivePresentationStyle(for:) in your delegate.