2

When I try to display a popover view controller programmatically it won't work and I don't know why. I've copied from multiple sources on the web and nothing seems to work, I get the same error in the console every time showing Warning: Attempt to present <AddFriendsPopoverViewController> on <MainPageViewController> whose view is not in the window hierarchy! I am lost and can't seem to figure out what the problem is, thanks in advance!

Here is my swift code in my viewDidLoad() function:

let addFriendsPopoverViewController = AddFriendsPopoverViewController()

override func viewDidLoad() {
    super.viewDidLoad()

    if (PFUser.currentUser()?["numberOfFriends"])! as! NSObject == 0 {
        print(PFUser.currentUser()?["numberOfFriends"])

        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let vc = storyboard.instantiateViewControllerWithIdentifier("AddFriendsPopoverViewController") as! UIViewController

        vc.modalPresentationStyle = UIModalPresentationStyle.Popover
        vc.preferredContentSize = CGSizeMake(50, 50)
        let popoverMenuViewController = vc.popoverPresentationController
        popoverMenuViewController!.permittedArrowDirections = .Any
        popoverMenuViewController!.delegate = self
        popoverMenuViewController!.sourceView = self.view
        popoverMenuViewController!.sourceRect = CGRectMake(
            100,
            100,
            0,
            0)

    self.presentViewController(vc, animated: true, completion: nil)

    }

}

EDIT I figured out that for a popover to work with iPhone the following code is required.

func adaptivePresentationStyleForPresentationController(controller: UIPresentationController!) -> UIModalPresentationStyle {
    // Return no adaptive presentation style, use default presentation behaviour
    return .None
}

3 Answers 3

5

Your view is not in the view hierarchy until it has been presented and not during viewDidLoad:

Move your code to viewDidAppear:

 if (PFUser.currentUser()?["numberOfFriends"])! as! NSObject == 0 {

    addFriendsPopoverViewController.modalPresentationStyle =   UIModalPresentationStyle.Popover
    addFriendsPopoverViewController.preferredContentSize = CGSizeMake(200, 200)
    let popoverMenuViewController = addFriendsPopoverViewController.popoverPresentationController
    popoverMenuViewController!.permittedArrowDirections = .Any
    popoverMenuViewController!.delegate = self
    popoverMenuViewController!.sourceView = self.view
    popoverMenuViewController!.sourceRect = CGRect(
        x: 50,
        y: 50,
        width: 1,
        height: 1)
    presentViewController(
        addFriendsPopoverViewController,
        animated: true,
        completion: nil)

}
Sign up to request clarification or add additional context in comments.

3 Comments

That did the trick, but i'm having trouble designating a size for it to show up over the present view controller, how could i go about doing that?
Did you init your addFriendsPopoverViewController from the storyboard?
Yes I did, I have updated my question with the instantiation code included. It loads the popover but it appears full screen despite me setting the preferredContentSize.
1

Your code is working right but u can not write that presentViewController code in ViewDidLoad method because viewdidLoad call till that time controller itself it not presented thats why it's not allow to presentViewController .

Write that same code in..

override func viewDidAppear(animated: Bool)

{
    var controller = UIViewController()
    controller.view.backgroundColor = UIColor .greenColor()
    presentViewController(controller, animated: true, completion: nil)

}

Comments

1

I have made it simple for multiple use and its ready to use and go. just copy and paste this extension.

extension UIViewController: UIPopoverPresentationControllerDelegate{

@discardableResult func presentPopOver(_ vcIdentifier: String, _ isAnimate: Bool = true,sender:UIView,contentSize:CGSize = .init(width: 100, height: 100)) -> (UIViewController){
    let popoverContentController = storyboard?.instantiateViewController(withIdentifier: vcIdentifier)
    popoverContentController?.modalPresentationStyle = .popover
    if let popoverPresentationController = popoverContentController?.popoverPresentationController {
        popoverPresentationController.permittedArrowDirections = .up
        popoverPresentationController.sourceView = sender
        popoverPresentationController.sourceRect = sender.bounds
        popoverContentController?.preferredContentSize = contentSize
        popoverPresentationController.delegate = self
        if let popoverController = popoverContentController {
            present(popoverController, animated: isAnimate, completion: nil)
        }
    }
    return popoverContentController ?? UIViewController()
}

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

public func popoverPresentationControllerDidDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) {
    
}

public func popoverPresentationControllerShouldDismissPopover(_ popoverPresentationController: UIPopoverPresentationController) -> Bool{
return true
}}

**how to use for presenting pop over on button click:-** 

   @IBAction func sortClicked(_ sender: UIButton) {
    presentPopOver("PopOverVC", sender: sender)
   }

***presenting pop over and to get and pass data:-*** 
@IBAction func sortClicked(_ sender: UIButton) {
    let vc = presentPopOver("PopOverVC", sender: sender) as? PopOverVC
    vc?.arrayNames = ["name1","name2"]
    vc?.callBack = {name in
        print(name)
        vc?.dismiss(animated: true)
    }
}
  

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.