Dismissing a presented UINavigationController in iOS6 - objective-c

In my root UIViewController I present a UINavigationController. The UINavigationController ultimately pushes another view (let's call it MyViewController). How can I dismiss the entire UINavigationController (and the views it has pushed) from MyViewController?
From MyViewController, I've tried calling [[self.navigationController presentingViewController] dismissViewControllerAnimated:NO completion:nil] but nothing happend. I've also tried first popping all the view controllers off the navigation controller but, still, the navigation controller was not dismissed.
Thanks!
UPDATE:
I've tracked down what's causing this issue but haven't been able to solve it. The UINavigationController described above is a custom subclass of UIImagePickerController (we'll call it CameraController) with source type UIImagePickerControllerSourceTypeCamera. Everything works as expected (using the answer provided below) until I set a custom cameraOverlayView on the CameraController in viewDidLoad. Commenting out the following lines gets things working:
self.showCameraControls = NO;
UIView *overlay = [[[NSBundle mainBundle] loadNibNamed:#"CameraController" owner:self options:nil] objectAtIndex:0];
self.cameraOverlayView = overlay;

You can call dismissViewControllerAnimated:NO on your self.navigationController itself.
[self.navigationController dismissViewControllerAnimated:NO completion:nil];

Related

removeFromParentViewController doesnot update UINavigationbar

I want to remove all the viewcontrollers from UINavigationController. So I am using this code.
for (UIViewController* controller in navigationController.viewControllers) {
[controller removeFromParentViewController];
}
After that I create an new viewController and push it.
UIViewController* newVC=[[UIViewController alloc] init];
[navigationController pushViewController:newVC animated:YES];
Issue is all the viewcontrollers popout perfectly and adding newVC but on pushing newVC the navigationbar is getting a back button and title of newVC. On clicking back button it animates to the navigationbar of oldVC with title of oldVC that I have already removed in above loop;
removeFromParentViewController is a UIViewController method, so it's normal it has nothing to do with UINavigationBar
In the case of a UINavigationController the popViewControllerAnimated: method handles the removeFromParentViewControllerpart for you, along with navigation bar.
you can directly update the whole array of viewControllersof UINavigationController, calling `setViewControllers:animated:
see Replacing rootView in navigationController
[navigationController setViewControllers:[NSArray arrayWithObject:newVC]];

Is this the right way to add a view?

I make a program that shows a table.
If people click the search I will add another view covering the original view. The original view is [BNUtilitiesQuick listnewcontroller];
[[BNUtilitiesQuick window] addSubview:[BNUtilitiesQuick searchController].view];
[[BNUtilitiesQuick searchController] viewWillAppear:YES] is indeed called. So it seems that UIView has a pointer to it's controller
However, the view that the [[BNUtilitiesQuick listnewcontroller] viewWillDisappear] is not called
Moreover, [[BNUtilitiesQuick listnewcontroller] viewWillAppear] is also not called even when the user has finished modifying search term with this code:
[self.view removeFromSuperview];
I think I may be missing something here. What exactly should I do anyway so IOs knows that the searchController.view will be covering listNewController?
This is NOT the right way to do it. If the searchController is a full screen controller you should present it modally using presentViewController or push it onto the navigation stack as #StuR suggested.
In case your search view covers only part of the listnewcontroller you should use the containment API in iOS5.
Inside listnewcontroller (parent view controller) you would write:
[self addChildViewController:self.searchController];
[self.view addSubview:self.searchController.view];
[self.searchController didMoveToParentViewController:self];
For more in-depth information check out the WWDC 2011 session video "Implementing UIViewController Containment". Also watch "The Evolution of View Controllers on iOS" from 2012 because there are some changes and deprecations in iOS6.
ViewController *viewController = [[ViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
I'd consider using pushViewController for adding a full screen view. addSubview is for views that don't cover the entire screen.
viewWillDisappear and viewWillAppear will only me called if you pop or push the given viewController. You are simple adding a subview with it's own viewController inside(on top) of the present viewController. As StuR said, if you want to dismiss the current ViewController you should use:
BNUtilitiesQuick *searchController = [BNUtilitiesQuick alloc] init];
[self.navigationController pushViewController:searchController animated:YES];
You can read more about ViewControllers here: http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/Introduction/Introduction.html#//apple_ref/doc/uid/TP40007457

Issues with changing UINavigationBar background when presenting modal view controller

I am using this method to change the backgrounds of my uiviewcontrollers. It generally works when I push a view controller.
However, if the viewcontroller is presented using
[self presentModalViewController:customViewController animated:YES];
then, this code doesnt work. Can anyone kindly suggest whats wrong ?
Code used:
To have an image in the navigation bar, you have to draw it yourself, which actually isn't that hard. Save this as UINavigationBar+CustomBackground.m (it adds a custom category to UINavigationBar):
#implementation UINavigationBar (CustomBackground)
- (void)drawRect:(CGRect)rect {
UIImage *image = [UIImage imageNamed:#"NavMain.png"];
[image drawInRect:CGRectMake(0, 0, self.frame.size.width, self.frame.size.height)];
}
#end
If you are running on iOS 5, then drawRect: is no longer called
You will need to either use the UIAppearance or subclass UINavigationController and use that to change to you image.
A tutorial for UIAppearance can be found here
(drawRect: will still work on versions below iOS 5)
Try this ,
UIColor *image = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:#"imagename.png"]];
replace image name.
not sure if this is it but have you tried
[self presentViewController:customViewController animated:YES completion:NULL]
And setting whatever modalViewStyle you deem appropriate for customViewController? According to the iOS documentation, presentModalViewController is deprecated, so you may have better luck using the above message call (especially since you only seem to be having this issue with modal view controllers)
You have to create a navigation controller, set the root controller and present it.
e.g.
UIViewController *vc = [[UIViewController alloc] init];
UINavigationController *cntrol = [[UINavigationController alloc] initWithRootViewController:vc];
[self presentModalViewController:cntrol animated:YES];
The method you is to set the navigation bar image in navigation controller.
But The new view controller you present is not using navigation method. Instead, you use Modal view Controller.
I have two solution for you:
--- 1 -----
still use Modal View Controller, just add that image on the top of new view controller.
[self.view addSubview:theImage];
---- 2 -----
use
[self.navigationController pushViewController:customViewController animated:YES];
instead of
[self presentModalViewController:customViewController animated:YES];
In this case, you are using navigation.
I will suggest the second one.

Navigating back to main ViewController dismissViewControllerAnimated dilemma

I have 2 ViewControllers directly connected with a push segue. I am navigating from first to second view controller by calling [self performSegueWithIdentifier:#"segueIdentifier" sender:sender]. On the second one I have an IBAction method that is bound to a "Done" button. Pressing that button should basically cause the first view controller to be displayed (sort of a back button). I managed to do that with:
NSArray *viewControllers = self.navigationController.viewControllers;
[self.navigationController popToViewController:[viewControllers
objectAtIndex:0] animated:YES];
I did try to achieve the same effect by using:
[self dismissViewControllerAnimated:YES completion:nil];
No matter what I tried though this didn't do the job. I am trying to understand what exactly am I missing but I can't figure it out. Does dismissViewControllerAnimated method work only with Modal segues ( this is the only thing that came to mind ).
Thank you
Yes,
- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^)(void))completion
is when a UIViewController is displayed modally.
- (UIViewController *)popViewControllerAnimated:(BOOL)animated
should do what you are seeking.
So basically, in your second VC:
[self.navigationController popViewControllerAnimated:YES];
You will save you a lot of trouble if you read the UIViewController and UINavigationController references. Twice ;)

Objective C: How to present modal view controller from appdelegate?

I am in the appdelegate of my application. How can I add a modal view controller in the "didfinishlaunching" method?
I tried the following but did not work
SomeViewController *vc = [[SomeViewController alloc]init];
[self.tabController.navigationController presentModalViewController:vc animated:NO];
EDIT:
I changed my implementation to the following
self.tabController.selectedViewController
= [self.tabController.viewControllers objectAtIndex:0];
SomeViewController *vc = [[SomeViewController alloc]init];
[self.tabController.selectedViewController presentModalViewController:vc animated:NO];
I checked that the 'selected view controller' is not null... however I am still not able to get the output I needed. Is there anything I am missing?
Assuming tabController and navigationController are not nil, the applicationDidFinishLaunching may be too soon to display the modal view controller.
Make sure you put that code after you make the window key and visible. [self.window makeKeyAndVisible];
If that does not work try listening for the UIWindowDidBecomeKeyNotification for that window
You can try delaying presentation of that modal a few seconds using performSelector:withObject:afterDelay: