UIPopoverController automatically resizes to maximum height on pushViewController

I have a popover containing a UINavigationController. I can display popover fine and it contains navController just fine. NavController contains a tableView, and when I select an item, it creates a new detailed view:

DeviceDetailViewController *detailViewController = [[[DeviceDetailViewController alloc] initWithNibName:@"DeviceDetailViewController" bundle:nil] autorelease]; 

Then I click on the new view controller:

  [self.navigationController pushViewController:detailViewController animated:YES]; 

This is when a problem arises: after clicking on a new view, popover resizes to the maximum height available on the iPad.

I tried to set the height of all the views in xib to a fixed height, not flexibility. I tried to explicitly set the height of the popover. I also tried using different view controllers as a child view. The problem remains: popover wants to automatically resize to maximum height whenever a new view is transferred to the navigation controller.

Here's a question that discusses trying to intentionally control the size of a popover when clicking new views:

I thought this could be a brute force method for controlling size. Oddly enough, however, this actually causes some quick graphic quirks (as if the view was recently animated) and then continuing to resize as described above.

In other words, something literally forces the popover to reach its maximum height, and it seems to happen after calling all the delegate methods.

Is this a navigation controller? Has anyone seen such things?

+68
uinavigationcontroller uipopovercontroller
Aug 11 '10 at 13:25
source share
13 answers

This fixed it for me after I had the same issue (a coincidence today too):

EDIT . Since contentSizeForViewInPopover deprecated in iOS7.0 , use preferredContentSize .

Original answer below :

In the detailViewController add the following:

 - (void)viewWillAppear:(BOOL)animated { CGSize size = CGSizeMake(320, 480); // size of view in popover self.contentSizeForViewInPopover = size; [super viewWillAppear:animated]; } 

You also want to add something similar to your original DeviceDetailViewController to prevent resizing when you click on the NavbarItem icon.

+123
Aug 11 '10 at 16:04
source share

As with viewWillAppear , another way to handle this is to override contentSizeForViewInPopover . Very brief:

 -(CGSize)contentSizeForViewInPopover { return self.view.bounds.size; } 
+30
Aug 04 2018-11-11T00:
source share

For iOS5

I recommend you do this in:

 - (void)viewDidLoad { [super viewDidLoad]; CGSize size = CGSizeMake(320, 480); // size of view in popover self.contentSizeForViewInPopover = size; } 
+30
Oct 14 '11 at 19:42
source share

I had a similar problem.

I got a popover from a toolbar button. A fellow traveler was installed in a certain size. It was a table view. When a table row was selected, a new view controller with a navigation controller was called.

When the back button was selected, popover became the default size (in my opinion, 320x1100) instead of the desired size.

Source:

  MyTableViewController *myVC = [[MyTableViewController alloc] init]; UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myVC]; UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navController]; popover.delegate = self; popover.popoverContentSize = CGSizeMake(400.0, 500.0); [myVC release]; [navController release]; [popover release]; 

I added one line to solve the problem. Of course, this is a kind of work, because I had to subtract the height of the header. Perhaps one of you could enlighten me with a better method. Anyway, it works.

  MyTableViewController *myVC = [[MyTableViewController alloc] init]; UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:myVC]; UIPopoverController *popover = [[UIPopoverController alloc] initWithContentViewController:navController]; popover.delegate = self; popover.popoverContentSize = CGSizeMake(400.0, 500.0); //Subtract the height of the header to match the total popover size (not just the view). myVC.contentSizeForViewInPopover = CGSizeMake(400.0, 500-44); [myVC release]; [navController release]; [popover release]; 

I believe that when the navigation controller is activated and the "Back" button is pressed, this leads to the fact that popover has its default size by default. By adding the contentSizeForViewInPopover property to the myVC controller, it forces a specific size.

Hope this will be helpful.

Kurt

+11
Feb 09 '11 at 4:19
source share

For iOS 7, use the following:

 - (void)viewDidLoad { [super viewDidLoad]; CGSize size = CGSizeMake(320, 768); // size of view in popover self.preferredContentSize = size; } 

UIViewController.contentSizeForViewInPopover was first deprecated in iOS 7.

+9
Feb 12 '14 at 15:39
source share

In response to graphic glitches with animation:

UIPopoverController animations conflict with UINavigation controller animations if you create a popover with a UINavigationController inside it. This causes graphical crashes during animation. To fix the problem, set the animated parameter to false when pressing other controllers or when displaying the toolbar.

View Buttons:

 [self.navigationController pushViewController:detailViewController animated:NO]; 

Toolbar display:

 [[self navigationController] setToolbarHidden:NO animated:NO]; 

Custom Animated: NO will make the animation correct in the UIPopoverController.

+6
Oct 19 '10 at 17:50
source share

Why not just set contentSizeForViewInPopover before pushing the next controller onto the navigation stack? No need to set dimensions in viewWillAppear etc.

 [nextController setContentSizeForViewInPopover:[self contentSizeForViewInPopover]]; [[self navigationController] pushViewController:nextController animated:YES]; 

Works on iOS 5.1

+5
Jun 14 '12 at 10:33
source share

A minor parameter on the borked board (which pointed me in the right direction, thanks for that!), This is what I do when you press the new controller to maintain the size until it is pressed:

 productViewController.contentSizeForViewInPopover = self.view.bounds.size; self.contentSizeForViewInPopover = self.view.bounds.size; [self.navigationController pushViewController:productViewController animated:YES]; 

I like it because I don’t need to hardcode the popover values ​​in each view controller (well, since I use them at different heights).

The self.contentSizeForViewInPopover line self.contentSizeForViewInPopover intended to save the size when the user hits. I think you could put this line in another place like viewWillAppear or anywhere.

Seems to work ...

+4
Nov 12 '10 at 7:20
source share

In the - (void) viewDidLoad view of all view controllers that you use in navigation, write the code:

 self setContentSizeForViewInPopover:CGSizeMake(320, 500)]; 
+2
Dec 03 '12 at 6:22
source share

There are two ways to set contentSizeForViewInPopover in a storyboard. You can configure the view controllers that are on your navigation controller in FreeForm and set the root views to the required size. Or you can save the simulated metric as output and check "Use explicit size" and set the size you want there.

Then, in each view controller that is inside your navigation controller, add the following ...

 - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; ["yourpopoverController" setPopoverContentSize:CGSizeMake(self. contentSizeForViewInPopover.width, seld.contentSizeForViewInPopover.height + self. navigationController.navigationBar.frame.size.height) animated:YES]; } 

In the transition animation, the new view will be aligned with the top, and then the height will be adjusted accordingly.

This way you do not need to override the contentSizeForViewInPopover or specify some other size, especially in your controllers. All this in the storyboard.

If one of your view controllers has a variable height, then you need to override the contentSizeForViewInPopover in this view, like this ...

 - (CGSize)contentSizeForViewInPopover { return CGSizeMake(450, "calculate your height here"); } 
+2
May 15 '13 at 14:45
source share

This stuff may have worked once, but not with xCode 6, in which contentSizeForViewInPopover is deprecated. Fortunately, he respected the loading time of the storyboard. I downloaded the xml editor (Xmplify) and hacked the storyboard. Set the contentSizeForViewInPopover key to the desired size. Save and replace (make the first copy) the storyboard.

More specific:

 < viewController> <value key="contentSizeForViewInPopover" type="size" width="450" height="280" / > </viewController> 
+1
Dec 16 '14 at 15:31
source share

Do not work for me when I use this:

 [UIPopoverController [UINavigationController] = root vc = [UIViewController vc1] => [UIViewController vc2] ] 

When a popup window appears, press the vc1 button and press vc2 on the navigation controller

Next, return to vc1 (root) by clicking the button in vc2 (popToRootViewController method);

We can see the popover resize itself, but the size of vc1 is old ... WHAT IS IT ???

Ok, now it works ... Add popover property to my controller

 self.contentSizeForViewInPopover = (CGSize){400, 200}; self.navigationController.contentSizeForViewInPopover = self.contentSizeForViewInPopover; self.popover.popoverContentSize = self.contentSizeForViewInPopover; 
0
Dec 01
source share

Running Swift 4 and iOS 11 is the only possible solution for me. Use showViewController:sender: and showDetailViewController:sender: instead of presentViewController:animated:completion:

From Apple Doc

The showViewController: sender: and showDetailViewController: sender: service methods offer the most adaptive and flexible way to display view controllers. These methods allow the view controller to decide how best to handle the presentation. For example, a container view controller may include a view controller as a child of its modal representation instead. The default behavior is a view controller.

0
Sep 14 '17 at 13:15
source share



All Articles