views:

929

answers:

2

I have a button inside the content of a UIPopoverController. This button runs a method called myAction.

MyAction has the form

- (void) myAction:(id)sender 

so, myAction receives the id of the caller button.

Now, inside this method I would like to dismiss the UIPopoverController, but the only thing I have is the ID of the caller button. Remember that the button is inside the UIPopoverController.

Is there a way to discover the ID of the UIPopoverController, given the button ID I already have?

thanks.

+6  A: 

Unfortunately no. At least, not within the standard practices. You might be able to travel up the responder stack to find it, but it's a hack, it's buggy, and it's really, really messy.

If you want to dismiss a popover by pushing a button, some place relevant should keep a reference to the popover. Usually that would be the owner of the popover (not the controller showed within the popover). When the button is pressed, it can send a message to the owner controller, which can then dismiss the popover.

You might be tempted to have the controller displayed inside of the popover be the owner of its own popover, but coding this way is brittle, can get messy (again), and may result in retain loops so that neither ever gets released.

Ed Marty
thanks. I will change the code!
Digital Robot
The second paragraph is extremely important in this answer. Remember, according to the iPad Programming Guide: " Be aware, though, that it is your responsibility to store a reference to the popover controller so that you can dismiss it. The system does not provide one by default." So, do not do a " release]" on it (will cause a crash anyway) until the parent view has entered the dealloc phase. (that is my safety method).
Jann
+1  A: 

I have this working, and I do not think it is a hack. I have a standard split view iPad app. I then added a method on my detail controller (the owner of the pop over) to handle the dismissal.

On the standard split view architechture, both the root and detail view controllers are available via the app delegate. So I bound a button click inside the pop over to call a method which gets the app delegate. From there I call the method on the detail controller to dismiss the pop over.

This is the code for the method on the View Controller that is displayed inside the popover:

- (void) exitView: (id)sender {
    MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];

    [appDelegate.detailViewController exitDrill];
}

Then the simple method to dismiss on the Detail View Controller:

- (void) exitDrill {
    if(dtController != nil){
      [dtController dismissPopoverAnimated: YES];
      [dtController release];
    }
}

I like the ability to do this because it give me a way to show a user how they can exit a pop over. This may not be necessary in future versions of the app; for right now, while this paradigm is still new to the platform, I prefer to let the users gexit a display in a couple fo different ways to make sure I minimize frustration.

MystikSpiral