Is it possible to present Modal view controller in didFinishWithResult?
I have an iPad application with 3 views Home,Start and Login. Start and Login modal views can be launched using start and login buttons in home view.
If clicked on login button, after successful login operation (didFinishWithResult) in login view I am able to dismiss the login view and but i am not able to launch the start view. But the control stays back on home view.
I am not getting any error for the above scenario.
Appdeligate.m :
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
HomeViewController * homeview=[[HomeViewController alloc] init];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:homeview];
self.rootViewController = navigationController;
[navigationController setNavigationBarHidden:YES];
self.rootViewController.view.frame = [[UIScreen mainScreen] applicationFrame];
[self.window addSubview:self.rootViewController.view];
[window makeKeyAndVisible];
Below is the method in the home view which Present the login modal view
Presenting Login Modal View
LoginViewController * vc1 = [LoginViewController loginViewControllerWithNavBar:YES];
vc1.boxLoginDelegate = self;
[self presentModalViewController:vc1 animated:YES];
Note : LoginVeiwController is Modal view controller which is presented
by HomeViewController. Is it right way to launch/present another modal
view controller (start controller) by dismissing LoginVeiwController
as below. Because whenever the LoginVeiwController dismissed the control stays back on HomeVeiwContrller rather than launching/presenting StartViewController:
Home View :
Below is the method in the home view which will dismisses the login view on successful login and tries to launch the start view.
- (void)loginViewController:(LoginViewController *)loginViewController didFinishWithResult:(LoginResult)result {
[self dismissModalViewControllerAnimated:YES];
startview = [[[startViewController alloc] init] autorelease];
[self.navigationController setNavigationBarHidden:YES];
[self presentModalViewController:startview animated:YES];
}
If I present the StartView directly on button click, it launches nicely, but not on didFinishWithResult
Try like this. I think it will be helpful to you.
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
HomeViewController * homeview=[[HomeViewController alloc] initWithNibName:#"HomeViewController" bundle:nil];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:homeview];
[self.window addSubview:navigationController.view];
[window makeKeyAndVisible];
return YES:
you need to restructure this line in your code [self dismissModalViewControllerAnimated:YES]; the reason being when dismiss is called, you loose self context of the controller and hence the line [self presentModalViewController:startview animated:YES]; is not showing any controller further.
to quicktest just comment dismiss line and see for yourself.
use this line when your currentViewController DissMiss then try bellow code...
[self performSelector:#selector(PresentView) withObject:nil afterDelay:0.2];
-(void)PresentView
{
[self.navigationController presentModalViewController:startview animated:YES];
}
hope,this help you....
:)
I guess it's about the animation. While the previous controller is dismissing,
[self presentModalViewController:startview animated:YES];
is called.
You can verify my guess by setting the animation to NO. Or directly use my suggestion to see if it works.
If I am correct, you can set them back to YES.
Besides, instead of directly calling the
[self presentModalViewController:startview animated:YES];
You can try:
[NSTimer scheduledTimerWithTimeInterval:0.5f target:self selector:#selector(showController) userInfo:nil repeats:No];
- (void)showController {
[self presentModalViewController:startview animated:YES];
}
edit:
I finally found out how I solve this similar problem before:
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
[UIView animateWithDuration:0.5
animations:^{
[self dismissModalViewControllerAnimated:YES];
}
completion:^(BOOL finished) {
NSURL *path = [info objectForKey:#"UIImagePickerControllerMediaURL"];
VideoConfirmViewController *videoConfirmCon = [[VideoConfirmViewController alloc]initWithFileURL:path];
[self presentModalViewController:videoConfirmCon animated:YES];
}
];
}
If you don't need compatibility with very old iOS versions it is better to use
-(void)presentViewControllerAnimated:completion:
-(void)dismissViewControllerAnimated:completion:
instead of
-(void)presentModalViewController:animated:
-(void)dismissModalViewController:animated:
In this case
- (void)loginViewController:(LoginViewController *)loginViewController didFinishWithResult:(LoginResult)result
{
[self dismissViewControllerAnimated:YES completion: ^{
startview = [[[startViewController alloc] init] autorelease];
[self.navigationController setNavigationBarHidden:YES];
[self.presentingViewController presentViewControllerAnimated:YES completion:NULL];
}];
}
Related
I have a tab bar application.
Here's launching code
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
[self.window makeKeyAndVisible];
self.tabBarController=[[UITabBarController alloc] init];
StartViewController *startViewController=[[StartViewController alloc] initWithNibName:#"StartViewController" bundle:nil];
NavRootViewController *navRootViewController=[[NavRootViewController alloc] initWithNavControllerWithSubViewController:startViewController];
HelpViewController *helpViewController=[[HelpViewController alloc] initWithNibName:#"HelpViewController" bundle:nil];
SettingsViewController *settingsViewController=[[SettingsViewController alloc] initWithNibName:#"SettingsViewController" bundle:nil];
AboutUsViewController *aboutUsViewController=[[AboutUsViewController alloc] initWithNibName:#"AboutUsViewController" bundle:nil];
[self.tabBarController setViewControllers:[NSArray arrayWithObjects: navRootViewController, helpViewController, settingsViewController, aboutUsViewController, nil]];
[[UIApplication sharedApplication] setStatusBarHidden:YES];
self.window.backgroundColor = [UIColor whiteColor];
self.window.rootViewController=self.tabBarController;
Application launched with 4 tab bar tabs.
This action is called after user presses start button in the first tab's navigation controller's root view controller
-(IBAction)startPressed:(id)sender
{
NSLog(#"startPressed: called");
RootViewController *vController=[[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
[self.navigationController pushViewController:vController animated:YES];
}
This works fine but I need to hide tab bar for my RootViewController
property hidesBottomBarWhenPushed does not work.
Help me please, how can it be done?
I hope this helps you:
- (void)viewWillAppear: (BOOL)animated
{
self.hidesBottomBarWhenPushed = YES;
}
Yea you have to add the modalview on window not on the viewcontroller of tabBar.
Try something like.. make an object of AppDelegate like:
AppDelegate *appDelegate=[[UIApplication sharedApplication]delegate];
then in next line add
[appDelegate.window.rootviewcontroller.view presentModalViewController:vController animated:YES];
or add your code [self presentModalViewController:vController animated:YES] in the viewDidAppear of the firstviewcontroller of tabBar.
What did you do to solve the problem??I would like to know that also.
If you don't want the main view to show the tab bar, you shouldn't be pushing it onto the navigation controller. Doing this causes the application to assume that this new controller is part of the navigation hierarchy. What is probably the best solution is to start your application on the RootViewController, and then present the navigation controller modally. When you're done with the navigation controller, have it call dismissModalViewController on itself.
Solved using this code:
-(IBAction)startPressed:(id)sender
{
NSLog(#"startPressed: called");
RootViewController *vController=[[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil];
UINavigationController *navController=[[UINavigationController alloc] initWithRootViewController:vController];
[vController setModalTransitionStyle:UIModalTransitionStyleCrossDissolve];
[((AppDelegate *)[UIApplication sharedApplication].delegate).tabBarController presentModalViewController:navController animated:YES];
}
Thanks to #iPhone Developer
UIViewController *nextViewController = [[UIViewController alloc] initWithNibName:#"NextViewController" bundle:[NSBundle mainBundle]];
// hide UITabbarController
nextViewController.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:nextViewController animated:YES];
[nextViewController release];
I am new to iPhone developer,
I have 4 page in my Application, my Application is viewBasedApplication.
I made my 1st page(LicAppViewController) as RootViewController, here is my code.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
self.viewController = [[[LicAppViewController alloc] initWithNibName:#"LicAppViewController" bundle:nil] autorelease];
UINavigationController *navigationController=[[UINavigationController alloc] initWithRootViewController:self.viewController];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
on button click i am navigation to 2nd page(PlanPage)
-(void)btnClicked{
PlanPage *viewController = [[PlanPage alloc]initWithNibName:#"PlanPage" bundle:nil];
[UIView beginAnimations:#"Flip" context:nil];
[UIView setAnimationDuration:0.7];
[UIView setAnimationCurve:UIViewAnimationOptionCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.navigationController.view cache:NO];
[self.navigationController pushViewController:viewController animated:YES];
[UIView commitAnimations];
[viewController release];
}
till now it is working fine, but when i select a row in 2nd page it crashes my application, i want to navigate to 3rd page(DetailPlanPage), here is my code
DetailPlanPage *nextController = [[DetailPlanPage alloc] initWithNibName:#"DetailPlanPage" bundle:nil];
[self.navigationController presentModalViewController:nextController animated:TRUE];
but when i write, this line:
[self.navigationController pushViewController:nextController animated:YES];
instead of:
[self.navigationController presentModalViewController:nextController animated:TRUE];
it's working fine. (I am not sure but crash of my application may be because of viewBased Application)
Thanks In Advance !
set rootview controller first
remove that code
[self.window addSubview:navigationController.view];
and include
self.window.rootViewController = navigationController;
in present modal view controller u can try like this
yourview *detailViewController = [[yourview alloc] initWithNibName:#"yourview" bundle:nil];
UIBarButtonItem *doneButton = [[UIBarButtonItem alloc ] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:#selector(dismiss)];
detailViewController.navigationItem.leftBarButtonItem = doneButton;
UINavigationController *nav;
nav=[[[UINavigationController alloc] initWithRootViewController:detailViewController] autorelease];
[self presentModalViewController:nav animated:YES];
[detailViewController release];
[doneButton release];
-(void) dismiss
{
[self dismissModalViewControllerAnimated:YES];
}
Try
[self presentModalViewController:nextController animated:YES];
you would also want to set the delegate for nextController to self and add a delegate function to dismiss Modal View Controller.
The most important difference is about semantics. Modal view controllers typically indicate that the user has to provide some information or do something. This link explains it more in depth:
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/ModalViewControllers/ModalViewControllers.html
When you present a modal view controller, the system creates a parent-child relationship between the view controller that did the presenting and the view controller that was presented. Specifically, the view controller that did the presenting updates its modalViewController property to point to its presented (child) view controller. Similarly, the presented view controller updates its parentViewController property to point back to the view controller that presented it. And also another link.
I have even tried implementing a delay right before the call to popToRootViewControllerAnimated however that does no good either. It just does not get called.
-(IBAction) btnSignOut{
[[self tabBarController]setSelectedIndex:0];
[[self navigationController]popToRootViewControllerAnimated:NO];//DOES NOT GET CALLED
Overview *overviewController = [[Overview alloc] initWithNibName:#"Overview" bundle:nil];
//Lets place OverView in navController
UINavigationController * navController = [[UINavigationController alloc] initWithRootViewController:overviewController];
// [[self navigationController] popToViewController:ComposeViewController animated:YES];
//Now lets display it
[self.tabBarController presentModalViewController:navController animated:YES];
[navController release];
[overviewController release];
}
It seems like the [self navigationController] does not contain any view to pop
Im my application I have the following code, the first bit runs when my application launches, and it presents a login screen in a modal view. With my rootController added to the window before that.
The Modal view will allow a user to log on, view terms and conditions and then if they accept the loadMainApp function is called.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
rootController.delegate = self;
[window addSubview:rootController.view];
LoginViewController *_loginViewController = [[LoginViewController alloc] initWithNibName:#"LoginView" bundle:[NSBundle mainBundle]];
self.loginViewController = _loginViewController;
[_loginViewController release];
UINavigationController *navi = [[[UINavigationController alloc]initWithRootViewController:loginViewController]autorelease];
navi.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[loginViewController release];
[rootController presentModalViewController:navi animated:YES];
[self.window makeKeyAndVisible];
return YES;
}
This next bit is called when the user accepts terms and conditions:
-(void)loadMainApp:(UIView *)fromView{
[fromView removeFromSuperview];
[window addSubview:rootController.view];
rootController.selectedIndex = 2;
rootController.delegate = self;
}
From here I want to be able to use the people picker which is a modal view and I attempt it with this code:
ABPeoplePickerNavigationController *picker =
[[ABPeoplePickerNavigationController alloc]init];
picker.peoplePickerDelegate = self;
[rootController presentModalViewController:picker animated:YES];
[picker release];
But nothing happens, when I try to present a modal view from my rootController nothing displays.
This appears to occur after this code in applicationDidFinishLaunching is run:
LoginViewController *_loginViewController = [[LoginViewController alloc] initWithNibName:#"LoginView" bundle:[NSBundle mainBundle]];
self.loginViewController = _loginViewController;
[_loginViewController release];
UINavigationController *navi = [[[UINavigationController alloc]initWithRootViewController:loginViewController]autorelease];
navi.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[loginViewController release];
[rootController presentModalViewController:navi animated:YES];
[self.window makeKeyAndVisible];
return YES;
If I dont display the login screen at all and instead just add my rootController
rootController.delegate = self;
[window addSubview:rootController.view];
in the applicationDidFinishLaunching function then everything works fine when I go to display the people picker.
Is there something fundamental that I am breaking here or can anyone spot what I may be doing wrong?
Are you dismissing the first modal view controller correctly, via thedismissModalViewControllerAnimated: method? If you're just removing the modal view controller's view from its superview, then probably a lot of paperwork is being left undone by UIKit.
What you should really do is something like this:
Add rootViewController to navigationController. Then add navigationController to the window.
In rootViewController's viewDidLoad method, set loginViewController's delegate to rootViewController and display the LoginViewController's instance as a modal.
When you are done with terms acceptance, do [delegate loginViewControllerFinished];.
Now in rootViewController, handle the loginViewControllerFinished method. This should contain a call to [self dismissModalViewControllerAnimated:YES]; to close the login modal view. Then you should launch ABPeoplePickerNavigationController as a modal view.
In AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Make sure rootViewController is initiated by this point.
UINavigationController *navigationController = [[[UINavigationController alloc] initWithRootViewController:rootViewController] autorelease];
[window addSubview:rootController.view];
[self.window makeKeyAndVisible];
return YES;
}
In RootViewController:
- (void)viewDidLoad {
[super viewDidLoad];
LoginViewController *loginViewController = [[[LoginViewController alloc] initWithNibName:#"LoginView" bundle:nil] autorelease];
loginViewController.delegate = self;
loginViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:loginViewController animated:YES];
}
- (void)loginViewControllerFinished {
[self dismissModalViewControllerAnimated:YES];
// Here we are closing one modal. And showing another after that.
ABPeoplePickerNavigationController *peoplePicker = [[[ABPeoplePickerNavigationController alloc] init] autorelease];
peoplePicker.peoplePickerDelegate = self;
[self presentModalViewController:peoplePicker animated:YES];
}
In LoginViewController:
// Make sure LoginViewController has delegate property in header.
// #property (nonatomic, assign) id delegate;
// And put this in implementation (.m) file. #synthesize delegate.
// Don't put release for delegate, since it's not retained. It's only 'assigned'.
- (void)done {
// Call this when you want to close loginViewController.
[delegate loginViewControllerFinished];
}
Hope this helps.
How can I navigate from one page to another page in xcode? remember without using the interface builder... I want the answer programmatically?
Pls be more precise if you want to get what you want.
If you are using view controllers within navigationcontroller you can make use of its pushViewController: or presentModalViewController:. Or if you just want to show another view you can just add the next view to existing view as subview.
Although your question is not much clear but still I would like to give a try...
You can use
UIViewController *yourViewController = [[YourViewControllerClass alloc] initWithNibName:#"<name of xib>" bundle:nil];
[self presentModalViewController:yourViewController animated:YES];
[yourViewController release];
In case the new view is also to be created programmatically, you can do that in the viewDidLoad method of YourViewControllerClass and change the initialization to
UIViewController *yourViewController = [[YourViewControllerClass alloc] init];
In YourViewController when you wish to come back to previous view on some button action you can use
[self dismissModalViewControllerAnimated:YES];
Another way that you can do is
UIViewController *yourViewController = [[YourViewControllerClass alloc] init];
[self addSubview:[yourViewController view]];
and to remove the view you can use
[self.view removeFromSuperview];
Hope this works for you, if yes please communicate....:)
//Appdelegate.m
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
UINavigationController *navigation = [[UINavigationController alloc]initWithRootViewController:self.viewController];
self.window.rootViewController = navigation;
[self.window makeKeyAndVisible];
return YES;
}
//In viewcontroller1.M
- (IBAction)GoToNext:(id)sender
{
ViewController2 *vc2 = [[ViewController2 alloc] init];
[self.navigationController pushViewController:vc2 animated:YES];
}