Handle to ModalPresentationFormSheet for Keyboard Dismissal - objective-c

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.

Related

What is best approach to add back button for first view controller in navigation controller?

I'm beginner iOS developer, so don't know how to solve my problem correctly. I have one navigation controller and want to make modal transition to another navigation controller that will have back button on it's first view controller.
In my first navigation controller I made this:
InfoViewController *destinatinViewController = [[InfoViewController alloc] initWithNibName:#"InfoViewController" bundle:nil];
[self presentViewController:destinatinViewController animated:YES completion:nil];
InfoViewController is UINavigationViewController.
Then I made this in InfoViewController (second navigation controller):
InfoRootViewController *rootViewController = [[InfoRootViewController alloc] initWithNibName:#"InfoRootViewController" bundle:nil];
[self pushViewController:rootViewController animated:NO];
For now I know how to add button to go back, but it has not styling (certainly arrow). As I understand because it is only one view in stack of second navigation controller.
So, I need your help to add styled back button for first view controller of navigation controller, because I don't want to make own styling (I'm lazy).
Thanks, for any advance!
PS: I made modal transition because, it has animations like from bottom or top. I tried to use custom animations for pushViewController, but in iOS 7 they're working not correctly.
I'll let someone else help you with the back button issue because I think it's a mistake to create one for a modal view controller that's presented from the bottom of the screen. Typically, such a modal view controller is dismissed with a cancel button or its equivalent. If you really think that you need a back button then you should probably push the view controller onto the existing navigation stack instead of presenting it modally.
However, I am happy to show you how to properly alloc/init a navigation controller and then present it.
I don't know why you're subclassing UINavigationController, but I'm going to pretend that you don't need to (which is probably the case).
InfoRootViewController *rootViewController = [[InfoRootViewController alloc] initWithNibName:#"InfoRootViewController" bundle:nil];
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:rootViewController];
[self presentViewController:navController animated:YES completion:nil];

How to push a MFMailComposeViewController? (iOS 5)

From a tableview I want to present a MFMailComposeViewController. I don't want to use the presentModalViewController:animated: method, but instead push the view controller, so it's consistent with the other animations from this table view.
Because MFMailComposeViewController is a UINavigationController and pushing a navigation controller is not supported, I used:
[[self navigationController] pushViewController:[mailComposer topViewController] animated:YES];
This works, but when I tap the Cancel button it gives the warning:
Presenting action sheet clipped by its superview. Some controls might not respond to touches. On iPhone try -[UIActionSheet showFromTabBar:] or -[UIActionSheet showFromToolbar:] instead of -[UIActionSheet showInView:].
The Cancel button at the bottom of the UIActionSheet doesn't respond to touches. Does anyone know whether it is possible to push a MFMailComposeViewController?
Presenting a MFMailComposeViewController as a modal view is consistent with Apple's HIG. Pushing it onto a navigation stack is not. Use -presentModalViewController:animated: (or -presentViewController:animated:completion: if executing on iOS 5 or greater)

Passcode ViewController Presentation from Modal View

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.

disable dismissal of uipopoverview 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.

Stop UIPopover from dismissing automatically

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