Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make UIPopoverController keep same position after rotating?

I can't keep popover the same position on the screen after rotation. Is there any good way to do that, because just setting some frame to popover works terrible after rotating.popover.frame = CGRectMake(someFrame); After rotation popover looks fine only if it is in the center of the screen.

like image 276
B.S. Avatar asked Jan 30 '12 14:01

B.S.


4 Answers

Apple has a Q&A on exactly this issue. You can find the details here:

Technical Q&A QA1694 Handling Popover Controllers During Orientation Changes

Basically, the technique explains that in your view controller's didRotateFromInterfaceOrientation method, you will present the pop over again as follows:

- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation
{
    [aPopover presentPopoverFromRect:targetRect.frame inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}

For more information, have a read of the article above, and also the UIPopoverController Class Reference:

If the user rotates the device while a popover is visible, the popover controller hides the popover and then shows it again at the end of the rotation. The popover controller attempts to position the popover appropriately for you but you may have to present it again or hide it altogether in some cases. For example, when displayed from a bar button item, the popover controller automatically adjusts the position (and potentially the size) of the popover to account for changes to the position of the bar button item. However, if you remove the bar button item during the rotation, or if you presented the popover from a target rectangle in a view, the popover controller does not attempt to reposition the popover. In those cases, you must manually hide the popover or present it again from an appropriate new position. You can do this in the didRotateFromInterfaceOrientation: method of the view controller that you used to present the popover.

like image 181
Max MacLeod Avatar answered Oct 31 '22 10:10

Max MacLeod


As of iOS 8.0.2 willRotateToInterfaceOrientation will not have any effect. As mhrrt mentioned, you need to use the delegate method:

- (void)popoverController:(UIPopoverController *)popoverController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView *__autoreleasing *)view

So for example if you want your popover to appear directly below a button that was pressed, you would use the following code:

- (void)popoverController:(UIPopoverController *)popoverController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView *__autoreleasing *)view
{
   CGRect rectInView = [self.theButton convertRect:self.theButton.frame toView:self.view];
   *rect = CGRectMake(CGRectGetMidX(rectInView), CGRectGetMaxY(rectInView), 1, 1);
   *view = self.view;
}
like image 43
John Stricker Avatar answered Oct 31 '22 10:10

John Stricker


In iOS 7 you can use - (void)popoverController:(UIPopoverController *)popoverController willRepositionPopoverToRect:(inout CGRect *)rect inView:(inout UIView *__autoreleasing *)view to reposition your UIPopoverController's view on interface orientation change.

See the UIPopoverControllerDelegate documentation.

like image 6
Markus Rautopuro Avatar answered Oct 31 '22 12:10

Markus Rautopuro


You can do this in didRotateFromInterfaceOrientation: method of the view controller that you used to present the popover.

Use setPopoverContentSize:animated: method for setting the size of the popover.

like image 5
dead_soldier Avatar answered Oct 31 '22 11:10

dead_soldier