9

I'm using UIPopoverPresentationController for popovers in an iOS app. When a navigation controller in a popover pushes a new view controller, the popover resizes to that view controller's preferredContentSize. But when the navigation controller pops a view controller off the stack, the popover does not resize to the previous size. How can I make it do that?

Possible duplicate of this question, but for the modern UIPopoverPresentationController.

Update: See here for example code illustrating the problem. Clone it and run it in an iPad simulator. Tap the Popover button and you get a popover with a nav controller. Tap the Push bar button item and you get a new taller VC on the stack (the size is in the nav bar). Pop and it doesn't resize back down to what it was.

Community
  • 1
  • 1
Tom Hamming
  • 10,577
  • 11
  • 71
  • 145

2 Answers2

20

Add this line:

self.navigationController.preferredContentSize = self.preferredContentSize;

to your viewWillAppear: method, so that it will now look like this:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    if (self.navigationController)
    {
        UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithTitle:@"Push" style:UIBarButtonItemStylePlain target:self action:@selector(onPush)];
        self.navigationItem.rightBarButtonItem = item;
        self.navigationItem.title = NSStringFromCGSize(self.preferredContentSize);
        self.view.backgroundColor = [UIColor lightGrayColor];

        self.navigationController.preferredContentSize = self.preferredContentSize;
    }
}

It will make sure that the navigation controller's preferred size is updated each time the displayed view controller changes. I tested it on your sample code and it resolved the issue.

Rony Rozen
  • 3,957
  • 4
  • 24
  • 46
  • Nice. I actually have a subclass of `UINavigationController` that I use to solve [this issue](http://stackoverflow.com/questions/32697436/how-can-i-change-the-opacity-of-the-overlay-behind-uipopoverpresentationcontroll/), so I overrode all the variants of push and pop and applied this principle there instead of in all the VCs I can have in nav controllers in popovers. – Tom Hamming Oct 06 '15 at 22:21
  • You are a master. – ΩlostA Feb 17 '17 at 14:15
2

Just add in your ViewController next code

- (void) viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    self.navigationController.preferredContentSize = CGSizeMake(200, self.parentViewController.childViewControllers.lastObject.preferredContentSize.height-100);
}

Here is the video. Hope this is behaviour which you expecting to get.

Alexey Bondarchuk
  • 2,002
  • 2
  • 20
  • 22
  • This looks promising. But can you make it generic, so you don't assume the +/- 100 point size change? – Tom Hamming Sep 30 '15 at 19:17
  • @Mr.Jefferson What do you mean promising? :) You wrote `Pop and it doesn't resize back down to what it was.` And now you can resize it back to original size. And I've thought that this was just an example from you to illustrate the problem. And `make it generic` is not clear task :) Can you provide some formula or description how pop-over should react? Because problem was not in generic... :) – Alexey Bondarchuk Sep 30 '15 at 19:21
  • Your answer assumes that the VC you're popping to is going to be 200 points wide and 100 points shorter than the one you're popping from. Can you rewrite your answer to not assume that? – Tom Hamming Sep 30 '15 at 19:23
  • 2
    I've used your [example](https://github.com/tomhamming/popover-resizing) from github. If you'll add to your original project provided code above size of popover will change if you'll pop back. P.S. You programmatically added +100 to height for `preferredContentSize` on `push`. So you just need to change `self.navigationController.preferredContentSize` instead of `self.preferredContentSize`. But if you'll describe what you need in more details - I'll try to solve this. Thanks. – Alexey Bondarchuk Sep 30 '15 at 19:29