Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IOS8 how to move an active popover

I have developed an app for iOS7 and now trying to update it for iOS8. Issue i have is the following:

The app screen orientation can be rotated and a few buttons in some cases move drastically. I have a few popovers that point to these buttons, so if a popover is open when screen rotates, button moves, i need the popover to also.

In iOS7 i did this by the following: When screen rotated i updated the constraints

- (void) updateViewConstraints 
{
    if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation))
    {
        self.Button.constant = (CGFloat)10;
    }
    else
    {
        self.Button.constant = (CGFloat)5;
    }
    [super updateViewConstraints];
} 

I also move the popover

- (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{

    if(TempDisplayPopoverController == examplePopoverController)
    {
        [examplePopoverController presentPopoverFromRect:[self ExamplePopoverPosition] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    }
}

I initially load the popover

- (void) LoadPopover{
    examplePopover = [[examplep alloc] initWithNibName:@"exampleP" bundle:nil];
    [examplePopover setDelegate:self];
    examplePopoverController = [[UIPopoverController alloc] initWithContentViewController: examplePopover];
    [examplePopoverController setDelegate:self];

    examplePopoverController.popoverContentSize = examplePopover.view.frame.size;

    TempDisplayPopoverController = examplePopoverController;


    if ([examplePopoverController isPopoverVisible])
    {
        [examplePopoverController dismissPopoverAnimated:YES];
    }
    else
    {
        [examplePopoverController presentPopoverFromRect:[self ExamplePopoverPosition] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
    }
}

[self ExamplePopoverPosition] just returns button position.

This all worked fine, i was happy, iPad was happy and all behaved.

Now due to iOS8 i have to change a few bits.

self.interfaceOrientation is depreciated

[examplePopoverController presentPopoverFromRect:[self ExamplePopoverPosition] inView:self.view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];

in didRotateFromInterfaceOrientation throws an error

"Application tried to represent an active popover presentation: <UIPopoverPresentationController: 0x7bf59280>"

I've managed to rectify self.interfaceOrientation by

- (void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [self SetUpScreen:toInterfaceOrientation];
}

- (void) SetUpScreen:(UIInterfaceOrientation)toInterfaceOrientation{
    if (toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft ||
        toInterfaceOrientation == UIInterfaceOrientationLandscapeRight)
    {
        self.Button.constant = (CGFloat)10;
    }
    else
    {
        self.Button.constant = (CGFloat)5;
    }
    [super updateViewConstraints];
}

but have no idea how to resolve the popover issue. I have tried

popoverController: willRepositionPopoverToRect: inView:

but just can't to seem to get it to work.

Can anyone advice

Thanks

like image 850
Display Name Avatar asked Oct 04 '14 08:10

Display Name


2 Answers

In iOS 8 you can use -viewWillTransitionToSize:withTransitionCoordinator: to handle screen size (and orientation) changes:

- (void)viewWillTransitionToSize:(CGSize)size
       withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator 
{
    [_popover dismissPopoverAnimated:NO];
    [coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context) {
         // Update your layout for the new size, if necessary.  
         // Compare size.width and size.height to see if you're in landscape or portrait.
    } completion:^(id<UIViewControllerTransitionCoordinatorContext> context) {
        [_popover presentPopoverFromRect:[self popoverFrame] 
                                  inView:self.view
                permittedArrowDirections:UIPopoverArrowDirectionAny 
                                animated:NO];
    }];
}

When you implement this method, the deprecated rotation methods like willAnimateRotationToInterfaceOrientation: will not be called when running on iOS 8.

like image 170
Darren Avatar answered Nov 10 '22 20:11

Darren


When using popoverController:willRepositionPopoverToRect:inView:, when reassigning to the rect parameter, try using:

*rect = myNewRect;

and not:

rect = &presentingRect;

Also, make sure you have properly assigned the popover controller's delegate.

like image 36
tjf Avatar answered Nov 10 '22 21:11

tjf