Search code examples
swiftuipopovercontroller

UIPopoverPresentationController popover displays over the entire view


I am trying to create a rightBarButtonItem that appears throughout my app. When this barItem is clicked I want to show a modal popup using UIPopoverPresentationController. I have been able to get the button to show up on the barItem on all the views. However when i click on the button the xib takes over the entire view (including nav bar, see image below). Please see the class below:

class MyAppsNavigationController: UINavigationController, UINavigationControllerDelegate, UIPopoverPresentationControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.delegate = self
        self.navigationBar.barTintColor = Colors.Red01.color()
        self.navigationBar.titleTextAttributes = [NSForegroundColorAttributeName : UIColor.white]
    }

    func navigationController(_ navigationController: UINavigationController, willShow viewController: UIViewController, animated: Bool) {
        viewController.navigationItem.rightBarButtonItem = UIBarButtonItem(image: #imageLiteral(resourceName: "Ellipsis"), style: .plain, target: self, action: #selector(displayMenu(sender:)))
    }

    func displayMenu(sender: UIBarButtonItem)
    {
        let filterVC =  DropdownMenuController(nibName: "DropdownMenuController", bundle: nil)
        let nav = UINavigationController(rootViewController: filterVC)
        nav.modalPresentationStyle = UIModalPresentationStyle.popover
        //nav.isNavigationBarHidden = true
        nav.preferredContentSize = CGSize(width: 200, height: 300)

        let popover = nav.popoverPresentationController! as UIPopoverPresentationController
        popover.permittedArrowDirections = .up
        popover.delegate = self
        popover.barButtonItem = self.navigationItem.rightBarButtonItem
        popover.sourceView = self.view;
        var frame:CGRect = (sender.value(forKey: "view")! as AnyObject).frame
        frame.origin.y = frame.origin.y+20
        popover.sourceRect = frame

        popover.delegate = self
        self.present(nav, animated: true, completion: nil)
    }

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

Result when clicked on the button:

First view with rightBarButtonImage

When clicked the popup takes over entire view:

When clicked the popup takes over entire view


Solution

  • Any chance you're not using the right delegate method? I think this looks better:

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

    Also, in this case sourceView and sourceRect is not needed: specifying a barButtonItem for the popover presentation controller is sufficient. https://developer.apple.com/documentation/uikit/uipopoverpresentationcontroller/1622314-barbuttonitem