16

I have a UIPopoverController with a subclass UINavigationController. Both the parent and child views are UITableviews.

When i call parent view originally with contentSizeForViewInPopover = (320,480) it works great.

When i click into the child view i resize the popover to contentSizeForViewInPopover = (320,780)

When return back to the parent view i cannot get the popover to resize back to contentSizeForViewInPopover = (320,480). the popover stays at the (320,780) size.

Been trying everything but just missing something. Anyone know how resize the view with UIPopoverControllers in the above scenario?

Thanks in Advance!!

skaffman
  • 398,947
  • 96
  • 818
  • 769
Abbacore
  • 385
  • 1
  • 3
  • 8
  • anyone? i still havent been able to resize my popover properly. its easy to increase in size but i cant get it to return to the smaller original size. – Abbacore May 31 '10 at 21:28
  • Good tagging is the way to get your question answered :) – skaffman Aug 02 '10 at 18:45

6 Answers6

24

The contentSizeForViewInPopover property of the view controller only sets the default (initial) size of its containing UIPopoverController. To resize the UIPopoverController at an arbitrary time, you must set its popoverContentSize property. Note that popoverContentSize is a property of the UIPopoverController and not of the view controller (so you'll probably need a reference to the popover controller around).

To reset the popover's size every time a view controller becomes the top view controller of a UINavigationController, you can use the UINavigationControllerDelegate protocol methods:

navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    if (viewController == viewControllerToResize) {
        referenceToUIPopoverController.popoverContentSize = CGSizeMake(320,480);
    }
}
cristoper
  • 441
  • 1
  • 6
  • 9
  • One potential gotcha is if the top UIViewController's contentSizeForViewInPopover has not been set, and you set the UIPopoverController's popoverContentSize you'll see the popover size first to the specified popoverContentSize, then to the default size (currently 320x1100). To solve this, i just set contentSizeForViewInPopover and then popoverContentSize. Disclaimer: this is not a well researched finding; rather just what i experienced in my current project on iOS 4.3. – kalperin Jun 17 '11 at 16:59
  • This one worked for me after trying for hours to get it right, but I had to add an extra delay before actually resizing the popover. – XCool Dec 12 '12 at 23:55
13

I had the same problem, but none of the above solutions worked for me. However, in trying to combine their approaches, I was inspired to try a slightly different way to attack the problem. This works for me:

-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    viewController.contentSizeForViewInPopover = navigationController.topViewController.view.frame.size;
}

I have three different popovers that each use navigation view controllers. This solution has the nice side effect of working for all of them because it doesn't make a specific reference to any of the popover controllers, but ends up using the popoverContentSize from the popover controller currently being used.

ry_donahue
  • 505
  • 2
  • 13
Chuck H
  • 7,434
  • 4
  • 31
  • 34
  • After trying all the methods in this thread and from other places this has been the only way for me to make this work. Thanks. – Marc M Nov 22 '11 at 12:18
  • I found this in the documentation: "This property contains the desired size for the view controller when it is displayed in a popover. By default, the width is set to 320 points and the height is set to 1100 points. " So if you do NOT set the contentSizeForViewInPopover explicitly , it will be 320x1100, this was driving me crazy as I thought apple would use sane defaults and make contentSizeForViewInPopover default to the view's frame or something, but apparently this is not the case. So set contentSizeForViewinPopover if you want your popover's to behave! – mgrandi Mar 19 '13 at 00:13
  • This worked for me as well, however I have no idea why. sizing popovers seems bugged. Sometimes they will resize properly, other times you have to set a weird string of methods just to get it to work properly. – LightningStryk Apr 22 '13 at 18:17
  • 1
    In the end this was the only soln for me, with a little modding. First, to clarify the approach, you have to define your UIViewController as a UINavigationControllerDelegate, and be sure to set it as the navigation controller's delegate, then you add the delegate method mentioned. I had to modify mine so that it set the nav controller's contentSizeForViewInPopover property to the VC's: `navigationController.contentSizeForViewInPopover = viewController.contentSizeForViewInPopover;` Also, I made sure each pushed VC had its contentSizeForViewInPopover property set upon creation. – daver Sep 03 '13 at 00:31
  • @daver setting the navigationController's property to match the view controller's fixed my issue. Thanks – ChrisH Oct 02 '13 at 21:05
2

In my project I had to dynamically change the size of the popover.

I made the original controller delegate of my popover content controller, and implemented it's delegate method that is called each time the size is changed:

The code is bellow, hope it helps somebody:

-(void) popover:(UIViewController*)controller didChangeSize:(CGSize)size{

    if ([controller class] == [AZViewController class]){
        if (!_popoverController){
            _popoverController = [[UIPopoverController alloc] initWithContentViewController:controller]; 
        }

        _popoverController.popoverContentSize = size;
    }
}
cduck
  • 2,691
  • 6
  • 29
  • 35
1

I think I had the same problem and I solved it by setting the size for the view in the popover every time the view was about to appear. Like this:


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

    self.contentSizeForViewInPopover = CGSizeMake(320, 444); //Set your own size
}

I hope this helps you.

Enrique R.
  • 750
  • 5
  • 16
  • thanks for the input enrigue. originally i tried this and just doesnt seem to do anything. imagine, the parent popover opens at 320x480. then i select a row which pushes a "child" view inside the popover that is 320x720. if i click the back button my "parent" view is still 320x720. – Abbacore Jun 01 '10 at 18:08
  • Can you detect when they push the back button or when the previous view shows again after they touch the back button? If you can detect that then you can place the 'contentSizeForViewInPopover' in that part of the code. – Enrique R. Jun 02 '10 at 15:21
1

I think I might have figured this out as I struggled with this issue for a while now. Might be a bit optimistic so please feel free to comment if this solution isn't working for you.

In each viewController displayed with the navigation hierarchy, set the contentSizeForViewInPopover property in the viewDidAppear: method to its appropriate size.

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self setContentSizeForViewInPopover:CGSizeMake(320, 320)];
}

Another thing I picked up is that when tapping back while editing a textField, the size stays small instead of the larger previous view. Call the resignFirstResponder method on your textField in the controller's viewWillDisappear.

I'm curious whether this solution works across sdks.

Schoob
  • 1,688
  • 1
  • 14
  • 18
0

After trying many things, the answer by @chuck-k helped me decently resolve for my UINavigationController popover woes in iOS7.

Here's what I did:

  • for each UIViewController within the UINavigationController I calculate the content size I want displayed in method - (CGSize)contentSizeForViewInPopover plus navigationController.navigationBar.frame.size.height (which is always 44 I think). I don't use any other popover functionality in these UIViewControllers.

  • I declared my UIViewController that creates the UINavigationController as a UINavigationControllerDelegate

  • Then in the delegate....

.....

- (void)navigationController:(UINavigationController *)navigationController willShowViewController: (UIViewController *)viewController animated:(BOOL)animated {

    BOOL popoverAnimation = NO;

    if ( self.myPopoverController.popoverContentSize.height < viewController.contentSizeForViewInPopover.height ) popoverAnimation = YES;

    [self.myPopoverController setPopoverContentSize:viewController.contentSizeForViewInPopover animated:popoverAnimation];
}

The height check compares the current view controller's popover content size to the "incoming" view controller popover content size. I use animation = NO when going from a larger --> smaller popover content size, because otherwise I get some jerky repositioning animation in iOS7. But peculiarly if animation = NO when going from a smaller --> larger popover content size, the popover size would increase to the size I was expecting but would not display content larger than the previously smaller content size... setting animation = YES resolved this issue for me. (I only check height because in my case the width is fixed.)

By using this technique almost everything finally works to my satisfaction and I hope this might help someone else.

Denton
  • 337
  • 3
  • 5