Search code examples
iosiphoneswiftuipopovercontroller

UIPopoverPresentationController on iPhone with iOS 10


I'm trying to display a ViewController as a popover on an iPhone. I have already been through several answers on SO and the rest of the web but none have worked so far. I wrote a simple app to test this.

ViewController.swift:

import UIKit

class ViewController: UIViewController, UIPopoverPresentationControllerDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(clicked(_:)))
    }

    func clicked(_ sender: Any) {
        let vc = UIViewController()
        vc.view.backgroundColor = UIColor.blue
        vc.preferredContentSize = CGSize(width: 200, height: 200)
        vc.modalPresentationStyle = .popover
        present(vc, animated: true, completion: nil)

        let ppc = vc.popoverPresentationController
        ppc?.permittedArrowDirections = .any
        ppc?.delegate = self
        ppc?.barButtonItem = navigationItem.rightBarButtonItem
    }

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

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

The storyboard has an empty ViewController embedded in a NavigationController.

Running this, I expected a popover view controller to show under the "done" button. Instead, the blue view controller is presented full screen.

Is there a way to change this behaviour?


Solution

  • You are connecting delegate after presenting view. How it will return .none from delegate and show as popover. Use this :-

        func clicked(_ sender: Any) {
    
            let vc = UIViewController()
            vc.view.backgroundColor = UIColor.blue
            vc.modalPresentationStyle = .popover
    
            vc.preferredContentSize = CGSize(width: 200, height: 200)
    
            let ppc = vc.popoverPresentationController
            ppc?.permittedArrowDirections = .any
            ppc?.delegate = self
            ppc?.barButtonItem = navigationItem.rightBarButtonItem
            ppc?.sourceView = sender
    
            present(vc, animated: true, completion: nil)
    
        }