EDIT: These issues appear to be fixed with iOS 7.1 / Xcode 5.1.1. (Perhaps earlier, since I could not test all versions. Definitely after iOS 7.0, since I tested this one.) When you create a popover segment from UIBarButtonItem , segue makes sure that clicking on popover again hides instead of showing a duplicate. It works correctly for the new pop UIPresentationController segments that Xcode 6 creates for iOS 8.
Since my solution may be of historical interest to those who still support earlier versions of iOS, I left it below.
If you keep a reference to the segue popover controller, discarding it before setting it to a new value when you call prepareForSegue:sender: again, all you avoid is the problem of getting multiple flowing popovers when you click the button again - you still don’t you can use the button to reject the popover, as recommended by HIG (and, as seen from Apple apps, etc.).
You can use ARC to nullify weak links for a simple solution:
1: Segue from the button
As in iOS 5, you could not do this work with segue with UIBarButtonItem , but you can on iOS 6 and later. (On iOS 5, you will have to switch from the view controller itself, then after calling the performSegueWithIdentifier: button performSegueWithIdentifier: call the button call
)
2: Use the popover link in -shouldPerformSegue...
@interface ViewController @property (weak) UIPopoverController *myPopover; @end @implementation ViewController - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { // if you have multiple segues, check segue.identifier self.myPopover = [(UIStoryboardPopoverSegue *)segue popoverController]; } - (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender { if (self.myPopover) { [self.myPopover dismissPopoverAnimated:YES]; return NO; } else { return YES; } } @end
3: There is no third step!
The good idea of using a null reference here is that after the popover controller is fired - whether it is programmatically in shouldPerformSegueWithIdentifier: or automatically when the user taps somewhere else outside the popover - ivar switches to nil again, so we will return to our initial state.
Without zeroing out weak links, we also need:
- set
myPopover = nil , rejecting it in shouldPerformSegueWithIdentifier: and - set yourself as the delegate of the popover controller to catch
popoverControllerDidDismissPopover: and also set myPopover = nil there (so that we will catch when the popover is automatically rejected).
rickster Apr 20 '12 at 0:10 2012-04-20 00:10
source share