Firstly, it would be advisable to check if a popover is displayed, it is also convenient to check if it was highlighted:
if ([self.popover isPopoverVisible]) { [self.popover dismissPopoverAnimated:NO]; }
Now the problem is that you are not getting the delegate callback - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController if you programmatically drop the popover like this, but you need a strong popover link until it is no longer visible.
The way to do this is to set a delay for the nil property until you return to the main run loop, since when you return to the main run loop, all animations will be completed, and thus the popover will no longer be visible.
You need to move the code setting popover to nil to another method:
- (void)releasePopover { self.popover.delegate = nil; self.popover = nil; }
Then, in the rotation callback, add this method to start in the main run loop, I would like to do this by adding a call operation to the main run loop:
if ([self.popover isPopoverVisible]){ [self.popover dismissPopoverAnimated:NO]; NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(releasePopover) object:nil]; [[NSOperationQueue mainQueue] addOperation:invocationOperation]; }
Finally, for cleanliness, you'll probably want to call -releasePopover from your callback - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController .
So, all together:
- (void)releasePopover { self.popover.delegate = nil; self.popover = nil; } - (void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration { if ([self.popover isPopoverVisible]){ [self.popover dismissPopoverAnimated:NO]; NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(releasePopover) object:nil]; [[NSOperationQueue mainQueue] addOperation:invocationOperation]; } } - (void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController { [self releasePopover]; }
Having said all this, if there is no good reason, you may just want the popover to be reused and only set it to zero when you receive low memory warnings and / or if your view is unloaded, as Chris Loonam replied: