I was wondering if there was a way to stop an iPad popover from dismissing automatically whenever you touch the screen outside the popover? If not, is there some kind of method similar to "popoverDidDismiss" that I could call to tell when the popover was dismissed?
Yes you can. This is right out of the Apple documentation.
When a popover is dismissed due to user taps outside the popover view, the popover automatically notifies its delegate of the action. If you provide a delegate, you can use this object to prevent the dismissal of the popover or perform additional actions in response to the dismissal. The popoverControllerShouldDismissPopover: delegate method lets you control whether the popover should actually be dismissed. If your delegate does not implement the method, or if your implementation returns YES, the controller dismisses the popover and sends a popoverControllerDidDismissPopover: message to the delegate.
Just return NO to the delegate method popoverControllerShouldDismissPopover:
Here is a link for further reading.
Popover Guide
- (BOOL) popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
return NO;
}
That does it for you and you may assign a specific bar button item or something else in your popover to dismiss the popover.
even u can use
self.modallnpopover = yes;
if you want to dismiss it in a particular view
self.modallnpopover = no;
if you dont want to dismiss it
Related
All,
I have a DetailViewController that has its class set to UIControl and there is a "backgroundTouched" IBAction method that handles those background touch events perfectly. When I change the DetailViewController to be presented modally, in a FormSheet, I lose the ability to detect background touches so the keyboard will not dismiss on background touch. I think the cause is that previously, the DetailView was taking up the entire screen so all of the delegate methods fired but now that it's being presented modally, these delegate and IBAction methods are no longer able to communicate.
Am I correct in my analysis of the problem and how do I get the modal presentation to report events?
Thanks
//Give it a nav controller
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
/****************************************************
*
* Use a modal form presentation for form
*
*
****************************************************/
//Use a form sheet style for DetailView
[navController setModalPresentationStyle:UIModalPresentationFormSheet];
//flip-horizontal transition
[navController setModalTransitionStyle:UIModalTransitionStyleFlipHorizontal];
[self presentViewController:navController animated:YES completion:nil];
}
It may be related to how Apple has chosen to handle keyboard dismissing during a modal presentation (i.e. basically don't hide it when it normally would hide. Rationale is that in a modal context it would likely go up and down too often).
see Modal Dialog Does Not Dismiss Keyboard The accepted answer on that question has a good explanation, and my answer provides a good generic solution when using Navigation Controllers.
I'm adding TabBarItem (Email) dynamically. When I finish with my email, I'm calling 'dismissModalViewControllerAnimated' but it's simply dismissing mail view. How do I unload the view controller?
in my email view controller I'm doing following:
- (void)viewDidLoad => I would like to unload this view controller
{
[super viewDidLoad];
[self showEMail:nil]; => this display and dismisses email (I'm not calling present.. and dismiss... in a row. I'm using delegate methods to present and dismiss, which is fine.)
[self presentModalViewController:picker animated:YES];
[self dismissModalViewControllerAnimated:YES];
}
after selecting my tab bar item, it's loading view controller(Lets say 'ABC View controller') which is presenting my mail modal controller. mail modal controller is being dismissed properly. but I would like to come back to previously selected tab item after unloading the 'ABC view controller'. is it possible? or am i doing something wrong here?
Thanks in advance
Rama
Rama, your question is hard to understand. maybe you need to use delegation for the view controller you are presenting.
In your code, calling [self presentModalViewController...] and [self dismissModalViewController...] in a row doesn't make sense.
You shall call the [self presentModalViewController...] in the first place, make the presenting view controller as the delegate (picker.delegate = self, for instance)
let the modal view controller do its business including exiting (like user hits cancel, close or whatever), then call the delegation method (something like [delegate didFinish...] or [delegate didCancel...]
now it's the presenting view controller's turn to response to the delegation method calling, you can do the modal view controller dismissing here
Note: many UIKit classes practice this pattern, such as UIAlertView, UIActionSheetView, MPMoviePlayerViewController, etc. You shall check them and make your own
I've solved problem by using ViewWiilAppear method to display mail modal presenter.
and i'm selecting the index of tab bar controller after dismissing mail modal presenter.
self.tabBarController.selectedIndex =0;
This solved my problem.
Cheers
I have a navigation controller I created in a storyboard. The forward and back functions work fine...The part I am struggling with is how I can save state of the application when the back button is pressed. Is there a way I can have my current view controller be notified when the back button is pressed?
How can I use viewWillDisappear in this case:
ReaderViewController *readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
readerViewController.title = model.title;
readerViewController.delegate = self;
[self.navigationController pushViewController:readerViewController animated:YES];
[readerViewController release];
(I am using a pdf reader library)
Well, the view controller that is on the top of the stack (presently on screen) will get the viewWillDisappear: and viewDidDisappear: messages.
viewWillDisappear: is a good place to save anything the user may have been editing or manipulating on that screen.
Edit to address your followup:
So when the user taps "back", you'll get these messages (I'm going to call the presenting view controller 'rootViewController')
readerViewController will get viewWillDisappear:
rootViewController will get viewWillAppear:
readerViewController will get viewDidDisappear:
rootViewController will get viewDidAppear:
So if you have access to the ReaderViewController source, you can add/edit methods for those events. You can also set a delegate on the navigation controller, and that delegate will get navigationController:willShowViewController:animated: and navigationController:didShowViewController:animated: as the user comes back.
But if you tell us more about this "ReaderViewController", maybe it has delegate methods you can implement to save whatever state it manipulates. What "pdf reader library" is this? And what state exactly are you trying to save?
I'm implementing a Passcode feature in my iPhone app which has a UITabBarController as a root view controller. I have everything working great in most situations, by displaying a modal Passcode ViewController from the tabBarController when the app goes into the background, like so:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
if ([[NSUserDefaults standardUserDefaults] valueForKey:kPasscodeStringKey]) {
PasscodeEntryVC *passcodeView = [[PasscodeEntryVC alloc] init];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController:passcodeView];
[tabBarController presentModalViewController:nav animated:NO];
}
}
My problem comes when the app is already displaying a modal view controller when it enters the background. Then, no passcode view appears. What would be the correct way to do this? Instead of just sending the message to the tabBarController to present the view, should I be checking first to see what the current view is, then have that present the passcode? If so, how is this done? Thanks.
First - you are leaking memory because you do not release your passcodeView and navigation controller nav.
Second - you could keep a simple BOOL variable that is updated whenever a modal view is presented or dismissed. If there is a modal view, just call dismissModalViewController:animated: in your applicationDidEnterBackground: method.
You could also check the frontmost view controller with [self.navigationController.topViewController class], but I have found this to be unreliable.
What I usually do is to ensure that any views I have that may present a modal view controller to dismiss the modal view controller whenever it is sent the UIApplicationWillResignActiveNotification notification, while over in my app delegate, I set it up exactly like yours.
One caveat though, is that whenever you dismiss the said modal view controllers, you need to ensure that you dismiss them with animated: set to NO before presenting your passcode view controller.
UIPopoverController automatically dismisses when we tap or touch outside the popoverview.
I want to restrict this automatic popover dismissal.
self.myPopovercontroller.passthroughViews=[NSArray arrayWithObject:self.view];
Duplicate of "is there a way NOT to have the popover dismissed when pressing outside it?"
There is a very simple and legit solution. In the view controller that presents your UIPopoverController, conform to the UIPopoverControllerDelegate protocol and implement the following delegate method. I just tested this and it does prevent popover to dismiss.
- (BOOL)popoverControllerShouldDismissPopover:(UIPopoverController *)popoverController
{
return NO;
}
Just make sure that you have set the delegate of your popover controller to the view controller that implements this.
You can dismiss the popover by using [popoverController dismissPopoverAnimated:NO]; method.
Have a read of the UIPopoverController documentation. Specifically...
When displayed, taps outside of the popover window cause the popover
to be dismissed automatically. To allow the user to interact with the
specified views and not dismiss the popover, you can assign one or
more views to the passthroughViews property. Taps inside the popover
window do not automatically cause the popover to be dismissed. Your
view and view controller code must handle actions and events inside
the popover explicitly and call the dismissPopoverAnimated: method as
needed.
Implement popoverControllerShouldDismissPopover: in the delegate, and you can stop it from disappearing unless you want it to.