Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UIBarButtonItem + popover segue creates multiple popovers

I've currently have an iPad app with a UIToolbar containing two UIBarButtonItems, each of which is connected to a popover segue.

When the user touches either of the UIBarButtonItems, the popover is created rather than toggled. This creates multiple, overlapping popovers. I've been able to close the previously created popover using the following code

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // First close the preferences popover if it's open per Apple guidelines
    if ([self.popoverA.popoverController isPopoverVisible]) {
        [self.popoverA.popoverController dismissPopoverAnimated:YES];
    }

    if ([self.popoverB.popoverController isPopoverVisible]) {
        [self.popoverB.popoverController dismissPopoverAnimated:YES];
    }
    ... code to manage segues ...
}

I also have UIButtons which create popover segues which behave normally. Due to this behavior of the popovers associated with UIBarButtonItems, my app is being rejected. Does someone have any suggestions or any code samples of a UIToolbar with multiple UIBarButtonItems that work correctly? The popovers do dismiss when the user touches outside the window,

like image 357
Timothy Newton Avatar asked Dec 22 '11 01:12

Timothy Newton


2 Answers

This is the proper way to do what you need to do:

- (BOOL)shouldPerformSegueWithIdentifier:(NSString *)identifier sender:(id)sender {
    if ([identifier isEqualToString:@"SurveyListPopover"]) {
        if (self.surveyListPopover == nil) {
            return YES;
        }
        return NO;
    }
    return YES;
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([segue.identifier isEqualToString:@"SurveyListPopover"]) {
        // Assign popover instance so we can dismiss it later
        self.surveyListPopover = [(UIStoryboardPopoverSegue *)segue popoverController];
    }
}

This ensures that the segue will be cancelled if an instance of the popover has already been displayed. You just need to make sure your popover object has an identifier in the storyboard.

like image 196
Brenden Avatar answered Nov 05 '22 08:11

Brenden


By the time you get messaged in -prepareForSegue:sender:, it's too late to cancel a segue.

In order to do this efficiently, you should create segues to your popovers from the view controller itself instead of the bar buttons so that they can still be programmatically executed. Now wire the UIBarButtonItems up to some methods that will conditionally present or dismiss the popover.

- (IBAction)showPopoverA
{
    if (self.popoverA.popoverController.popoverVisible)
        [self.popoverA.popoverController dismissPopoverAnimated:YES];

    [self performSegueWithIdentifier:@"ShowPopoverA"];
}
like image 8
Mark Adams Avatar answered Nov 05 '22 08:11

Mark Adams