presentModalViewController not showing from separate UIViewController - iphone

I have a UIViewController with this method:
-(void)prepareToShowVault {
...
UINavigationController *passcodeNavigationController = [[UINavigationController alloc] initWithRootViewController:passcodeViewController];
[self.navigationController presentModalViewController:passcodeNavigationController animated:YES];
[passcodeViewController release];
[passcodeNavigationController release];
}
When called from another method in this UIViewController, it works just fine. But when called from another UIViewController, this method fires but the code doesn't display a new modalViewController, presumably because the UIViewController with the above method isn't active. How can i make this work?

In the UIViewController docs it says
modalViewController
The controller for the active modal view—that is, the view that is temporarily displayed on top of the view managed by the receiver. (read-only)
So I would guess that unless your view controller is the active one you will not see the modal view that it presents.
Therefore you need to either be in that view controller or add the method to the other view controller as well possibly using a category that you add to both.

Why are you pushing a navigation controller? A navigation controller is already present. Don't create a navigation controller. I think you should simply be doing-
[self.navigationController presentModalViewController:passcodeViewController animated:YES];
HTH,
Akshay

Related

Go to first view controller in app

I need to go to the first view in my app. I have a few views pushed onto the stack then a modal navigation controller and more views pushed onto that.
The problem I'm having is that using [[self navigationController] popToRootViewControllerAnimated:YES]; only goes back to the first view in the modal stack.
And I can't get [[self navigationController] popToViewController:.. to work because the true first view controller isn't accesible with [[self navigationController] viewControllers].
Any ideas on how to accomplish this? Thanks.
Do this:
[[self navigationController] dismissModalViewControllerAnimated:YES];
That will get you back to the VC that modally presented the navigation controller. Getting farther back after that depend on how you pushed those "few views" before the navigation controller.
Edit - explanation to get to the deepest root...
It sounds like those "few views" are on another, underlying navigation controller's stack. This can be a little tricky, because the clean way to get farther back in that stack is to have that underlying navigation controller pop to it's own root. But how can it know that the modal VC on top of it is done?
Let's call the view controller that did the modal presentation of second navigation controller VC_a. It's a modally presented navigation controller whose topmost VC is VC_b. How can VC_a know to pop to it's navigation root when VC_b modally dismisses itself?
The good answer (usually) is that VC_b decided to dismiss itself for a reason - some condition in your app/model changed to make it decide to be done.
We want VC_a to detect this condition, too. When VC_b gets dismissed, and VC_a gets a viewWillAppear message because it's about to be uncovered:
// VC_a.m
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (/* some app condition that's true when VC_b is done */) {
// I must be appearing because VC_b is done, and I'm being uncovered
// That means I'm done, too. So pop...
[self.navigationController popToRootViewControllerAnimated:NO];
} else {
// I must be appearing for the normal reason, because I was just pushed onto the stack
}
}
You need to do it by using the delegation pattern. Specifically, by creating a protocol that implements the delegate's respondsToSelector method.
See this post for complete details. It should be almost exactly what you are looking for. I had to do something similar, except I only needed to pop one view off the navigation stack instead of using popToRootViewControllerAnimated:.
For iOS6...
[self.view.window.rootViewController dismissViewControllerAnimated:YES completion:nil];
In AppDelegate.m class create method with bellow flow...
-(void)MethodName{//your method name
YourViewController *objViewController = [[[YourViewController alloc] initWithNibName:#"YourViewController" bundle:nil] autorelease]; ///define your viewcontroller name like "FirstViewController"
UINavigationController *yourNavigationController = [[[UINavigationController alloc] initWithRootViewController:objViewController] autorelease];
self.window.rootViewController = yourNavigationController;
}
When you want redirect on firstview just call this method from appdelegate object....

Unable to get presentViewController to work

I copied a working viewcontroller class from another project into a new project. I can't get the view to load in the new project. In the old project I used presentModalViewController. In the new I cannot get the view to load using either presentModalViewController or presentViewController
I am trying to load the present the view from my main view controller.
Here is what my main view controller interface looks like...
// ViewController.h
#import <UIKit/UIKit.h>
#import "RequestDialogViewController.h"
#interface ViewController : UIViewController <RequestDialogViewControllerDelegate> {
}
- (void)requestDialogViewDidDismiss:(RequestDialogViewController *)controller withResponse:(NSString*)response;
I am using presentModalViewController like this...
RequestDialogViewController *requestIPViewController = [[RequestDialogViewController alloc] initWithNibName:#"RequestDialogViewController" bundle:nil];
navigationController = [[UINavigationController alloc] initWithRootViewController:requestIPViewController];
[self presentModalViewController:navigationController animated:YES];
and presentViewController like this...
RequestDialogViewController *requestIPViewController = [[RequestDialogViewController alloc] initWithNibName:#"RequestDialogViewController" bundle:nil];
[self presentViewController:requestIPViewController animated:YES completion:nil];
What am I missing in the new project? The init method fires, but viewDidLoad does not and nothing is displayed.
Thanks
If ViewController is the root view controller, it can't present a modal view controller from within its own viewDidLoad, because at that point it doesn't have information like the screen size.
If other view controllers have already displayed, this will work. If the root view controller is a UINavigationController, you will see a view sliding in from the right while the modal view slides up from the bottom.
Anyway, for your ViewController, the soonest you could present it is after it has become visible. Using a timer for this is unreliable; older and slower devices have dramatically longer load times.
For more reliability, implement viewDidAppear: for ViewController. Do still use your timer system to add an additional delay; a fraction of a second should be sufficient. Although presenting the modal view controller from within viewDidAppear worked for me in the iOS 5.1 simulator, Presenting a modal view controller when loading another ViewController says it sometimes doesn't happen.
I have it resolved. I was trying to present the view from view did load of the main view controller. Not sure why it does not work there, but instead I am now setting a timer which calls a method to present the view controller after the main view loads and it works fine now using...
[self presentViewController:requestIPViewController animated:YES completion:nil];
Thanks to those who replied.
As #Dondragmer said, if you want to present your viewController in root view's viewDidLoad, it will fail.Once your viewController is ready for that, you can present your new viewController.
So, you can do that in
- (void)viewDidLayoutSubviews {
//present here
}
I encountered the same problem. But my situation is the presentViewController is called after the dismissViewControllerAnimated for another ViewController. My solution is to move the presentViewController to completion block of dismissViewControllerAnimated.
Present a modalViewController:
For the benefit of all starting programmers, type it instead of copy paste.
myVC *viewController = [[myVC alloc]initWithNibName:#"myVC" bundle:nil];
viewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:viewController animated:YES];
[viewController release];
It looks like you were trying to present a nav controller as a view controller in the first sample, then you were using the wrong method in the second one.

Dismiss ModalViewController from another viewController in subview

I've got a view called A open with presentModalViewController Method, inside this view I loaded secondary view using:
new_view = [[new_websongs alloc] initWithNibName:#"new_websongs" bundle:nil];
[mysubview addSubview:new_view.view];
ok, to here it's ok but now I need to dismiss the first view "A" calling a method [self dismissModalViewControllerAnimated:YES] situated if first "A" viewController from secondary view controller (new_view) but not work! the code is:
self.Aviewcontroller = [[Aview alloc] init];
[Aviewcontroller dismissModalViewControllerAnimated:YES];
[Aviewcontroller release];
Please help ME!!!!
Thanks
Did u try [self.parentViewController dismissModalViewControllerAnimated:YES];
You have a logical problem. Start reading View Controller Programming Guide for iOS
The view controller that present an modal view controller must dismiss it or the modal view controller must dismiss it self
Totally agree with other answers; think logically about the order of view controller order and type. So think about which controllers are shown modally, and those shown via a navigation controller.
You can of course set a number of view controllers with:
- (void)setViewControllers:(NSArray *)viewControllers animated:(BOOL)animated
without animation, then when required call say:
- (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated
to show a specified view controller further up your stack of view controllers.
Hope this helps think about what you need to do? It's often a good idea to think about the order and type of view controllers in your app's interface in a separate project - where you can try it out on the device itself.
try this it should work
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
This works if you are presenting a modal view from a UISplitViewController. It can also be applied in so many other ways...
First, create an instance in your .h file for your appDelegate, (AppDelegate_iPad *appDelegate) then put this in your viewDidLoad or comparable method:
ipadDelegate = (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];
Now, present the first modal view like this:
YOURVC *vc = [[YOURVC alloc] initWithNibName:#"YOURVC" bundle:nil];
[ipadDelegate.splitViewController presentModalViewController:vc animated:YES];
[vc release];
Say you have a subview, like a UITableView, and want to dismiss the modal from the didSelectRowAtIndexPath. All you have to do to dismiss your modal with a subview is create another ipadDelegate instance inside your subview's .h (if needed), reference the [[UIApplication sharedApplication] delegate] again, and dismiss:
[ipadAppDelegate.splitViewController dismissModalViewControllerAnimated:YES];
Essentially, as long-winded as it may be, use your appDelegate's controller to present and dismiss the the modal if you need to maintain a persistent reference to the presentingViewController...because all the things above just don't work in my case.
If you're presenting with your ipadDelegate, make sure you check the mode of presentation in your MainWindow_iPad.xib. Your "Transition Style" should be "Cover Vertical" and "Presentation" should be "Current Context" or your modal may present behind other views.

How do I destroy a view that is added by pushViewController?

After adding a view by pushViewController method, there will be a back button in the navigation bar to pop the view off the stack. However, it seems that iOS won't destroy the view after popping it off the stack so when will it be destroyed? Can we destroy it manually when popping out the view?
Generally the pattern is like this:
- (void)pushSomeViewControllerOnStack
{
SomeViewController* someViewController = [[SomeViewController alloc] initWithNibName:#"SomeView" bundle:nil];
[self.navigationController pushViewController:someViewController animated:YES];
[someViewController release];
}
In other words, the navigation controller will do its own retain of the view controller, which means you also need to release it yourself, since there's an init. The navigation controller will also take care of releasing this controller when appropriate.
You should implement the viewDidUnload and dealloc methods within your UIViewController subclasses.
When a UINavigationController pops a view controller off its stack the code within those methods will be executed.
You should read the View Controller Programming Guide for iOS: Navigation Controllers documentation from Apple's iOS Developer Library as well as the class reference documentation for the UINavigationController and UIViewController classes so that you will better understand the view controller life cycle and what to expect when various application events occur.

How do you properly set up a secondary view to support a navigation Controller on the iPhone?

I have an iPhone app that shows a simple view (View 1) that has a button. When the user presses this button, View 2 slides into view using the call
[self presentModalViewController:self.view2 animated:YES];
I want View 2 to support a navigation controller. All the code I find tells you how to set up a Navigation Controller App, but I can't figure out how to set this up using IB.
What I have done is to create a plain view2.xib file. I set the file's owner class to view2.
I add a navigation Controller to the XIB. I create an IBOutlet called view2Nav in view2.h for a UINavigationController. I link view2Nav to the NavigationController in view2.xib.
I then create a view3 class with view3.xib. I set the RootViewController in view2.xib to be of class view3 and set its NIB name to view3.
Then I go back and run the program. When I press my button on view 1, the app crashes as it tries to create view 2.
I know I must be missing a setting or something.
MySecondViewController *secondVC = [[MySecondViewController alloc] initWithNibName:#"MySecondViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:secondVC];
[self presentModalViewController:navigationController animated:YES];
[secondVC release];
[navigationController release];
Forget about IB. Do anything in code :) It is faster and you will exactly know why and how it works.
I'm not sure whether you can pass a self.view2 to presentModalViewController. If self.view2 is a subclass of UIViewController, you can. If it is a simple UIView, you shouldn't. If fact you can't at all.