mario595
mario595

Reputation: 3761

Disable UIBarButtonItem when popover is dismissed

I am new in iOS development and I am trying to show a popover when tap a barButtomItem. So far I have this:

-(IBAction)shareButtonPressed :(id)sender{    
    UIViewController *popoverViewController = [[UIViewController alloc] initWithNibName:@"ShareOptionsViewController" bundle:nil];
    popoverViewController.contentSizeForViewInPopover = CGSizeMake(319, 422);

    self.popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverViewController];
    [self.popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny  animated:NO];
}

This code works and when I tap the correct button, the popover is showed. The problem is when the popOver is showed, if I tap again the button, the app crashes. I know is because it is trying to alloc a variable that is already created. I think the solution should be disable the button when the popover loads but I don't know how to activate again once the popover is dismissed.

Am I right? How can I enable the button when the popOver is dismissed?

Upvotes: 0

Views: 746

Answers (5)

tkanzakic
tkanzakic

Reputation: 5499

you can detect if the popover is shown and dismissed:

- (IBAction)shareButtonPressed :(id)sender{
    if (self.popoverController) {
        [self.popoverController dismissPopoverAnimated:YES];
        self.popoverController = nil;
    } else {
        UIViewController *popoverViewController = [[UIViewController alloc] initWithNibName:@"ShareOptionsViewController" bundle:nil];
        popoverViewController.contentSizeForViewInPopover = CGSizeMake(319, 422);

        self.popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverViewController];
        [self.popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny  animated:NO];
    }
}

or if you just want to disable the button:

- (IBAction)shareButtonPressed :(id)sender{
    ...
    UIButton *button = (UIButton *)sender;
    button.enabled = NO;
}

but in this case you will have to detect when the user close the popOver to enable the button again. You can do this adopting the UIPopoverController delegate (see documentation) in your class

Upvotes: 0

Luiz
Luiz

Reputation: 90

First you should disabled the button in your shareButtonPressed method.

-(IBAction)shareButtonPressed :(id)sender{    
UIViewController *popoverViewController = [[UIViewController alloc] initWithNibName:@"ShareOptionsViewController" bundle:nil];
popoverViewController.contentSizeForViewInPopover = CGSizeMake(319, 422);

self.popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverViewController];
[self.myButton setEnabled:NO];
[self.popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny  animated:NO];
}

Then you make your view controller comply with the UIPopoverControllerDelegate protocol. After that you implement the popoverControllerDidDismissPopover method.

-(void)popoverControllerDidDismissPopover:(UIPopoverController *)popoverController
{
if (!self.myButton.enabled) // Just to make sure the button is disabled.
    [self.myButton setEnabled:YES];

}

Upvotes: 1

Ganapathy
Ganapathy

Reputation: 4614

Just modify your code like this...

-(IBAction)shareButtonPressed :(id)sender{    
        UIViewController *popoverViewController = [[UIViewController alloc] initWithNibName:@"ShareOptionsViewController" bundle:nil];
        popoverViewController.contentSizeForViewInPopover = CGSizeMake(319, 422);

         if(self.popoverController)
          {
            [self.popovercontroller dismissPopoverAnimated:YES];
            self.popovercontroller = nil;
           }   
        self.popoverController = [[UIPopoverController alloc] initWithContentViewController:popoverViewController];
        [self.popoverController presentPopoverFromBarButtonItem:sender permittedArrowDirections:UIPopoverArrowDirectionAny  animated:NO];
    }

Upvotes: 0

apascual
apascual

Reputation: 2980

Look at this "event --> responsible" list:

1) Button pressed --> MainViewController - IBAction

2) Popover shown --> MainViewController - IBAction

3) Button disabled --> MainViewController - IBAction

4) Popover dissmis --> popoverDelegate - popoverControllerDidDismissPopover

5) Button enabled --> popoverDelegate - popoverControllerDidDismissPopover

So, if the delegate of your popover is the MainViewController, you would have access to the button, if it is a different class you'll probably have to set up a protocol in order to enable the button back.

Tell me if you need any further explanations...

Upvotes: 0

Miro Hudak
Miro Hudak

Reputation: 2215

Just check if instance is already created.

-(IBAction)shareButtonPressed:(id)sender
{
    if (self.popoverController == nil) {
        self.popoverController = alloc/init...;
        [_popoverController present...];
    } else {
        if (self.popoverController.popoverVisible)
            [self.popoverController dismissPopoverAnimated:YES];
        self.popoverController = nil;
    }
}

There is a possibility, it will be garbage collected before animation completes, yielding invalid user experience. Then, if possible, I would pre-create the instance in viewDidLoad or contructor or so and then just present and dismiss as needed, checking visible property.

Upvotes: 0

Related Questions