Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS: dismiss popOver generated with Interface Builder with button within the popOver

I have a button which leads to a popOver, all created in Interface Builder. The popOver is closed when I press somewhere outside of it, but I would also like to implement a button within the popOver which does that.

I found a solution by Giorgio Barchiesi dating back to 2011, however I fail to implement it. Here's his solution:

In the implementation file of the source view controller:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue destinationViewController] isKindOfClass:[MyDestViewController class]]) {
        MyDestViewController* viewController = (MyDestViewController*)[segue destinationViewController];
        UIStoryboardPopoverSegue* popoverSegue = (UIStoryboardPopoverSegue*)segue;
        [viewController setPopoverController:[popoverSegue popoverController]];
    }
}

In the header file of the destination view controller:

@property (weak, nonatomic) UIPopoverController* popoverController;

In the implementation file of the destination view controller:

@synthesize popoverController;

Same file, whenever you want to dismiss the popover:

[popoverController dismissPopoverAnimated:YES];

i could call the last function when the button is pressed. My problem is that XCode gives me an error on the [viewController setPopoverController:[popoverSegue popoverController]] line: ARC Semantic Issue: No known class method for selector 'setPopOverController'

What did I miss to implement?

like image 263
user2014551 Avatar asked Jan 27 '26 04:01

user2014551


2 Answers

Here is the method I use:

Open your storyboard file, select the segue arrow and open the Attributes Inspector (Option - Command - 4) and identifier fill in a sensible name, like "myPopoverSegue".

In your Source View Controller define a variable right after @implementation :

@implementation ViewController
{
    __weak UIPopoverController *myPopover;
}

Then, again in the Source VC:

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
    if ([segue.identifier isEqualToString:[dict objectForKey:@"myPopoverSegue"]]) {//@"segue" is your segue name. You can use isKindOfClass as you do currently, I prefer this method.
        myPopover = [(UIStoryboardPopoverSegue *)segue popoverController];
    }
}

-(void)closePopover{
    [myPopover dismissPopoverAnimated:YES];
}

In the end of your Source VC's viewDidLoad method write:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(closePopover) name:@"popoverShouldDismiss" object:nil];

Finally, whenever you want to dismiss the popover:

 [[NSNotificationCenter defaultCenter] postNotificationName:@"popoverShouldDismiss" object:nil];

Hope this helps! This way you will also be able to change the segue to a different controller without changing your code.

like image 151
Hristo Avatar answered Jan 28 '26 19:01

Hristo


You can add the delegate < UIPopoverControllerDelegate > to your class and override the delegate method:

 - (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
 {
     return NO;
 }

This will prevent the popover to be dismissed when user presses anywhere on screen. Now you can dismiss your popover inside the button's selector method by using:

  [popoverController dismissPopoverAnimated:YES];
like image 31
Amit Avatar answered Jan 28 '26 20:01

Amit



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!