Popover presentation style on iPhone devices - possible any more?

Viewed 3276

I'm trying to define a popover view attached to a view like this:

desired popover appearance

Here's my code:

class MyController: UIViewController, UIPopoverPresentationControllerDelegate {

    ...

    func displaySignOut(_ sender: UIButton) {
        let vc = UIStoryboard(name: "Main", bundle: nil)
            .instantiateViewController(withIdentifier: "signOutPopover")
        vc.modalPresentationStyle = .popover
        vc.preferredContentSize = CGSize(width: 100, height: 30)
        present(vc, animated: true, completion: nil)

        let pc = vc.popoverPresentationController!
        pc.sourceView = sender
        pc.sourceRect = sender.bounds
        pc.delegate = self
    }

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

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

Because the popover is so small, I'd like to use this style on all devices. I've followed the usual advice (e.g., here) on overriding adaptivePresentationStyle to return UIModalPresentationStyle.none.

This works fine on iPad devices, but on iPhones, it doesn't. On smaller iPhone devices, it comes up full screen all the time. On larger screens (e.g., iPhone 7 Plus), it comes up wrong, but, weirdly, switches to a popover presentation (in both portrait and landscape) if I rotate the device after the popover appears. (If I dismiss the popover and bring it up again, it's wrong again until I rotate the device.) Furthermore, in landscape it comes up in a strange configuration (not full screen as in portrait):

How the popover appears in landscape on iPhone 7 Plus

Unlike with a popover presentation, this does not dismiss if I tap outside the popover view itself.

The Apple documentation says (in part):

In a horizontally compact environment, popovers adapt to the UIModalPresentationOverFullScreen presentation style by default.

The "by default" strongly suggests that there's a way to override this behavior. But (as is consistent with this post), overriding adaptivePresentationStyle in the delegate doesn't seem to be the way to do this any more (although it used to work). So is there a new way to modify the default behavior?

I'm using XCode 8.3.3 and Swift 3.1, targeting iOS 9+.

2 Answers

iOS 15 has some new ways to solve this problem. Take a look at the WWDC21 Session "Customize and Resize Sheets in UIKit" https://developer.apple.com/wwdc21/10063 Pretty simple new interface for popovers and customized sheets. Shows how to do non-modal interaction with pop over and the view behind it.

Related