I am using MVYSideMenu in my application and I can present new controller using "changeContentViewController" of MVYSideMenu but it presents new controller so from here I want to pop back to my root(HomeViewController) so I have done lot of research on this but couldn't find solution.
So if anybody knows the solution please help me.
Thanks in advance.
MVYSideMenu is making rootViewController, when you are trying to open any view from this. If you are making rootViewController, then you can not able to pop from that.
So if you want to go back, then you have to Push that view instead of making rootViewController.
I think, Right Now you are using following code for open any controller for side menu:
ChildViewController *contentVC = [[ChildViewController alloc] initWithNibName:#"ChildViewController" bundle:nil];
appDelegate.nav = [[UINavigationController alloc] initWithRootViewController:contentVC];
appDelegate.nav.navigationBarHidden=TRUE;
[[self sideMenuController] changeContentViewController:appDelegate.nav closeMenu:YES];
So Please use following code instead of above code. Here nav is object of UINavigationController in AppDelegate.
ChildViewController *contentVC = [[ChildViewController alloc] initWithNibName:#"ChildViewController" bundle:nil];
[appDelegate.nav pushViewController:contentVC animated:YES];
[[self sideMenuController] changeContentViewController:appDelegate.nav closeMenu:YES];
So You can able to push any view from side menu. And Now just try to pop this view. I am sure that you can able to pop this view after using this.
Make sure that, If you do this, then may be memory leakage is there. Because all times viewControllers are adding to the navigation controller. So My suggestion is, don't do this, if you can convince your client. :) Otherwise, you have to make your own side menu.
EDIT :-
Yes we can able to enable / disable side menu for some view controllers. Please add following methods into MVYSideMenuController.m file. And call this method from viewWillAppear of your viewControllers.
- (void)addGestures {
if (!_panGesture) {
_panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:#selector(handlePanGesture:)];
[_panGesture setDelegate:self];
// [self.view addGestureRecognizer:_panGesture];
}
if (!_tapGesture) {
_tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(toggleMenu)];
[_tapGesture setDelegate:self];
[self.view addGestureRecognizer:_tapGesture];
}
}
- (void)removeGestures{
[self.view removeGestureRecognizer:_panGesture];
_panGesture = nil;
}
You can easily call this methods LocalNotifications. May be addGestures already there. You can remove gestures by calling removeGestures method when you needed in your controller. But do not forgot to addGestures when you needed side menu after removing gestures.
Hope, this is what you're looking for. Any concern get back to me. :)
I'm trying use Kal calendar in my project. Here is what I understand to be the case so far:
Whichever view controller that calls Kal must implement the UITableViewDelegate method "didSelectRowAtPath"
Issue:
My view controller that calls Kal already has an existing tableview (one of the cells would call Kal)
To solve this, I've attempted to push an intermediary view controller from a cell in my main tableview as follows:
ScheduleViewController *svc = [[ScheduleViewController alloc] init];
[svc setTitle:#"Schedule"];
[self.navigationController pushViewController:svc animated:YES];
From ScheduleViewController's viewDidLoad, I'm pushing the actual Kal calendar:
KalViewController *kal = [[KalViewController alloc] init];
[kal setDelegate:self];
[kal setTitle:#"Schedule"];
[self.navigationController pushViewController:kal animated:NO];
So once I do this, I can get the calendar to show up. However, I can't seem to cleanly get back to my main menu using the back button. I created a back button in ScheduleViewController:
[kal.navigationItem
setBackBarButtonItem:[[UIBarButtonItem alloc] initWithTitle:#"Back"
style:UIBarButtonItemStyleBordered
target:self
action:#selector(test)]];
I've put this in a few different places (viewDidLoad, viewWillAppear) and can't get it to work. When I click "Back" it still goes to ScheduleViewController instead of all the way back. "test" never gets called. I've tried popToRootViewController, [[self.presentingViewController presentingViewController] dismissViewController], and a few others. Just doesn't want to work.
Is this the best way to go about using Kal?
How can I popToRootViewController (skipping ScheduleViewController) using this method?
Thanks! This is my first post so please let me know if there's anything I can do to make the question less confusing.
Well, finally got it I think. I ended up removing the intermediary view controller. I think I just didn't understand what was going on earlier...I've now done the following:
instead of my main view controller (w/the existing tableview) being the delegate, I made the KalDataSource also be the UITableViewDelegate. So my DataSource handles both populating the calendar and selection of an event.
added id datasource as in ivar in main view controller
changed the "didSelectRowAtPath" method to:
dataSource = [[EventsDataSource alloc] init];
KalViewController *kal = [[KalViewController alloc] init];
[kal setDelegate:dataSource];
[kal setDataSource:dataSource];
[kal setTitle:#"Schedule"];
[self.navigationController pushViewController:kal animated:YES];
Everything now appears to be okay.
I am inside a root view controller. and then allocate the secondviewcontroller
SecondViewControl *second=[[SecondViewControl alloc] init];
[self presentModalViewController:second animated:NO];
The second viewcontroller 's view not showing up
AddSubView method works though.
[self.view addSubView:second.view];
why presetModalViewController is not working?
Usually you'll allocate the SecondViewControl with a .xib file that actually defines the user interface. Consider using a line like this (broken for readability):
SecondViewControl *second = [[SecondViewControl alloc]
initWithNibName:#"SecondView"
bundle:nil];
Without the accompanying .xib to define the view, you may be left with a view controller that doesn't have the necessary properties set to actually support user interaction, and so presentModalViewController: may have trouble there.
Preface: I am not using *.xib files.
I instantiate a UINavigationController in a class that effectively serves as my 'rootViewController'. This 'rootViewController' also has two UITableViewController members that are drawn on different sections of the iPad screen. One of which is set as the root view for the navigation controller. Let's call it tableViewControllerA.
The problem is, when I invoke pushViewController on a valid UINavigationController, I see no effect:
[tableViewControllerA.navigationController pushViewController:tableViewControllerX animated:YES];
I've gathered from the posts I've searched today, that this push method should in turn cause the screen to redraw the top of stack controller.view. This is not what I'm seeing.
It seemed there was a disconnect in my implementation, and it was time to reference a working example in my environment (xcode 4.0). Assuming the canned templates would provide a working basis, I created a new navigation-based applications. I simply modified didFinishLaunchingWithOptions: as follows.
UIViewController *view1 = [[UIViewController alloc] init];
UIViewController *view2 = [[UIViewController alloc] init];
view1.title = #"view1";
view2.title = #"view2";
[self.navigationController pushViewController:view1 animated:YES];
[self.navigationController pushViewController:view2 animated:YES];
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:view1];
[view1 release];
[view2 release];
I found similar results. When I launch the simulator the screen title reads the title of whatever the self.window.rootViewController is pointing at. With the code as is, the title of the resulting top screen reads "view1". When I initWithRootViewController:view2, the resulting top screen reads "view2".
So please tell me I'm stupid cuz xyz...
Thanks.
Here are some references and suggestions:
Simple tutorial for navigation based application:
http://humblecoder.blogspot.com/2009/04/iphone-tutorial-navigation-controller.html
Here is another one to create the step by step navigation controller and adding the views:
http://www.icodeblog.com/2008/08/03/iphone-programming-tutorial-transitioning-between-views/
and here a bit advance with navigation + tab bar controller:
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/CombiningToolbarandNavigationControllers/CombiningToolbarandNavigationControllers.html
Without seeing your code, I have 2 theories:
Your syntax and calls are wrong when you do the push. Use this as a model:
-(void)Examplemethod {
AnotherClassViewController *viewController = [[[AnotherClassViewController alloc] initWithNibName:#"AnotherClassView" bundle:nil] autorelease];
[self.navigationController pushViewController:viewController animated:YES];
}
You are never adding the navigation controller to the view hierarchy which never adds the view either. Take a look at this.
Note:
See accepted answer (not top voted one) for solution as of iOS 4.3.
This question is about a behavior discovered in the iPad keyboard, where it refuses to be dismissed if shown in a modal dialog with a navigation controller.
Basically, if I present the navigation controller with the following line as below:
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
The keyboard refuses to be dismissed. If I comment out this line, the keyboard goes away fine.
...
I've got two textFields, username and password; username has a Next button and password has a Done button. The keyboard won't go away if I present this in a modal navigation controller.
WORKS
broken *b = [[broken alloc] initWithNibName:#"broken" bundle:nil];
[self.view addSubview:b.view];
DOES NOT WORK
broken *b = [[broken alloc] initWithNibName:#"broken" bundle:nil];
UINavigationController *navigationController =
[[UINavigationController alloc]
initWithRootViewController:b];
navigationController.modalPresentationStyle = UIModalPresentationFormSheet;
navigationController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:navigationController animated:YES];
[navigationController release];
[b release];
If I remove the navigation controller part and present 'b' as a modal view controller by itself, it works. Is the navigation controller the problem?
WORKS
broken *b = [[broken alloc] initWithNibName:#"broken" bundle:nil];
b.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:b animated:YES];
[b release];
WORKS
broken *b = [[broken alloc] initWithNibName:#"broken" bundle:nil];
UINavigationController *navigationController =
[[UINavigationController alloc]
initWithRootViewController:b];
[self presentModalViewController:navigationController animated:YES];
[navigationController release];
[b release];
This has been classified as "works as intended" by Apple engineers. I filed a bug for this a while back. Their reasoning is that the user is often going to be entering data in a modal form so they are trying to be "helpful" and keep the keyboard visible where ordinarily various transitions within the modal view can cause the keyboard to show/hide repeatedly.
edit: here is the response of an Apple engineer on the developer forums:
Was your view by any chance presented with the UIModalPresentationFormSheet style? To avoid frequent in-and-out animations, the keyboard will sometimes remain on-screen even when there is no first responder. This is not a bug.
This is giving a lot of people problems (myself included) but at the moment there doesn't seem to be a way to work around it.
UPDATE:
In iOS 4.3 and later, you can now implement `-disablesAutomaticKeyboardDismissal' on your view controller to return NO:
- (BOOL)disablesAutomaticKeyboardDismissal {
return NO;
}
This fixes the issue.
Be careful if you are displaying the modal with a UINavigationController. You then have to set the disablesAutomaticKeyboardDismissal on the navigation controller and not on the view controller. You can easily do this with categories.
File: UINavigationController+KeyboardDismiss.h
#import <Foundation/Foundation.h>
#interface UINavigationController (KeyboardDismiss)
- (BOOL)disablesAutomaticKeyboardDismissal;
#end
File: UINavigationController+KeyboardDismiss.m
#import "UINavigationController+KeyboardDismiss.h"
#implementation UINavigationController(KeyboardDismiss)
- (BOOL)disablesAutomaticKeyboardDismissal
{
return NO;
}
#end
Do not forget to import the category in the file where you use the
UINavigationController.
In the view controller that is presented modally, just override disablesAutomaticKeyboardDismissal to return NO:
- (BOOL)disablesAutomaticKeyboardDismissal {
return NO;
}
I solved this by using the UIModalPresentationPageSheet presentation style and resizing it immediately after I present it. Like so:
viewController.modalPresentationStyle = UIModalPresentationPageSheet;
viewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:viewController animated:YES];
viewController.view.superview.autoresizingMask =
UIViewAutoresizingFlexibleTopMargin |
UIViewAutoresizingFlexibleBottomMargin;
viewController.view.superview.frame = CGRectMake(
viewController.view.superview.frame.origin.x,
viewController.view.superview.frame.origin.y,
540.0f,
529.0f
);
viewController.view.superview.center = self.view.center;
[viewController release];
If you toggle a different modal display you can get the keyboard to disappear. It's not pretty and it doesn't animate down, but you can get it to go away.
It'd be great if there was a fix, but for now this works. You can wedge it in a category on UIViewController and call it when you want the keyboard gone:
#interface _TempUIVC : UIViewController
#end
#implementation _TempUIVC
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
#end
#implementation UIViewController (Helpers)
- (void)_dismissModalViewController {
[self dismissModalViewControllerAnimated:NO];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardDidHideNotification object:nil];
[self release];
}
- (void)forceKeyboardDismissUsingModalToggle:(BOOL)animated {
[self retain];
_TempUIVC *tuivc = [[_TempUIVC alloc] init];
tuivc.modalPresentationStyle = UIModalPresentationCurrentContext;
[self presentModalViewController:tuivc animated:animated];
if (animated) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(_dismissModalViewController) name:UIKeyboardDidHideNotification object:nil];
} else
[self _dismissModalViewController];
[tuivc release];
}
#end
Be careful with this though as you viewDidAppear / viewDidDisappear and all those methods get called. Like I said, it's not pretty, but does work.
-Adam
You could also work around this in a universal app by simply checking the idiom and if it's an iPad, don't pop up the keyboard automatically at all and let the user tap whatever they want to edit.
May not be the nicest solution but it's very straightforward and doesn't need any fancy hacks that will break with the next major iOS release :)
Put this code in your viewWillDisappear: method of current controller is another way to fix this:
Class UIKeyboardImpl = NSClassFromString(#"UIKeyboardImpl");
id activeInstance = [UIKeyboardImpl performSelector:#selector(activeInstance)];
[activeInstance performSelector:#selector(dismissKeyboard)];
I found that disablesAutomaticKeyboardDismissal and adding a disablesAutomaticKeyboardDismissal function didn't work for my UITextField in a modal dialog.
The onscreen keyboard just wouldn't go away.
My solution was to disable all text-input controls in my dialog, then re-enable the relevant ones a fraction of a second later.
It seems as though when iOS sees that none of the UITextField controls are enabled, then it does get rid of the keyboard.
I'm sure you have looked at this, but you are sure that your controller class is properly hooked up as the UITextField delegate, right?
maybe don't return NO, but YES. So it can go away.
And you have a textFieldShouldEndEditing returning YES as well?
And why are you firing [nextResponder becomeFirstResponder]?! sorry i see now
I also have a number of UITextViews
which all have their "editable"
property set to FALSE.
May we assume none of them, by any chance, has a tag value of secondField.tag+1? If so, you're telling them to become first responder, instead of resigning the first responder. Maybe put some NSLog() in that if structure.
For those having trouble with UINavigationController, see my answer to a similar question here:
https://stackoverflow.com/a/10507689/321785
Edit:
I consider this an improvement to Miha Hribar's solution (since the decision is taking place where it should), and as opposed to Pascal's comment regarding a category on UIViewController
may be not a perfect solution ,but works
[self.view endEditing:YES];
from wherever your button or gesture is implemented to present modal
Swift 4.1:
extension UINavigationController {
override open var disablesAutomaticKeyboardDismissal: Bool {
return false
}
}