Unable to navigate to next page iPhone - iphone

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.

Related

Nav Bar button loading random view before loading appropriate view

I have a back button on my answer view controller (a view controller that displays answers) if the user hits the back button I created it switches to a view that has the title of "Back" and just an empty tableview, before switching back to my main view of where all the questions to be answered are displayed. Why is this happening? Its a very brief thing, but definitely noticeable!
UINavigationBar *navBar = [[UINavigationBar alloc] initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 48)];
navBar.delegate = self;
UINavigationItem *backItem = [[UINavigationItem alloc] initWithTitle:#"Back"];
[navBar pushNavigationItem:backItem animated:NO];
UINavigationItem *topItem = [[UINavigationItem alloc] initWithTitle:#"Question"];
[navBar pushNavigationItem:topItem animated:NO];
topItem.leftBarButtonItem = nil;
[self.view addSubview:navBar];
- (BOOL)navigationBar:(UINavigationBar *)navigationBar shouldPopItem:(UINavigationItem *)item
{
ViewController *controller = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:controller animated:YES completion:nil];
return true;
}
- (void)navigationBar:(UINavigationBar *)navigationBar didPopItem:(UINavigationItem *)item
{
ViewController *controller = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
controller.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentViewController:controller animated:YES completion:nil];
}
You're creating your own UINavigationBar and UINavigationItem instances and you probably shouldn't be. The situation you describe is exactly what a UINavigationController is for. When using a UINavigationController it creates the UINavigationBar and each UIViewController that you show on screen (push into the navigation controller) has its own UINavigationItem (with the title taken from the title of the view controller).
The reason you get an empty 'view' titled "Back" is that you're creating it:
UINavigationItem *backItem = [[UINavigationItem alloc] initWithTitle:#"Back"];
[navBar pushNavigationItem:backItem animated:NO];
Dispense with all of this, create a UINavigationController and make your question view controller it's root view controller, then add the navigation controller to the screen. Then when a question is answered, push the answer view controller:
[self.navigationController pushViewController:answerViewController animated:YES];

UITabBarController Issue

I want to create something like below.
RootView does not have TabBar, From the second view there should be TabBar.
What I have currently done is, I am using UINavigationController as controller calass
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIViewController *rootController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
navigationController = [[UINavigationController alloc] initWithRootViewController:rootController];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window addSubview:navigationController.view];
[self.window makeKeyAndVisible];
return YES;
}
But how can I use UITabBar with tabBarController from SecondViewController?
create the objects of the second view and then push your view with the tabbarcontroller
From Storyboard embed your SecondViewController in TabBar. Select your controller and go to Editor -> Embed in -> TabBar Controller! I'm from my mobile..sorry if i have any mispells!
You need to push your Tabbar controller's object. Initialize your tab bar controller's object and add all other controller objects to the tabbar controller's viewcontroller array.
On button action:-
1> Initialize tab bar controller and suppose you name its object as objTab;
2> objTab.viewcontrollers = [NSArray arrayWithObjects:..] ---> Objects of all viewcontrollers that are a part of your tab bar controller. Thus all objects need to be created first.
3> self.navigationcontroller pushViewController: objTAb
Something like this should do the trick (not using ARC):
//vc1, vc2, vc3 = your view controllers
NSArray *viewControllersArray = [NSArray arrayWithObjects:vc1,vc2,vc3, nil];
UITabBarController *tabBarController = [[UITabBarController alloc] init];
[tabBarController setViewControllers:viewControllersArray];
[self.navigationController pushViewController:tabBarController animated:YES];
[tabBarController release];
What you want to do is create the UITabBarController and push that along the navigation stack.
For Sample Write loadnewview method at appdelegate .Use buttonPressed method for button action or any object action of first view controller as shown below to display tab bar from second view controller.
I have taken two tabs for sample so I wrote Capacity as 2. You can take up to 5.
-(IBAction)buttonPressed:(id)sender
{
HomeViewController *homeVC=[[HomeViewController alloc]initWithNibName:#"HomeViewController" bundle:nil];
[self.navigationController pushViewController:homeVC animated:YES];
[appDelegate loadnewview];
}
-(void)loadnewview
{
if(!self.tabBarController)
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.delegate=self;
NSMutableArray *localcontrollerarray = [[NSMutableArray alloc] initWithCapacity:2];
UIViewController *viewController1 = [[HomeViewController alloc] initWithNibName:#"HomeViewController" bundle:nil];
UINavigationController *navi1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
[localcontrollerarray addObject:navi1];
UIViewController *viewController2 = [[ScanViewController alloc] initWithNibName:#"ScanViewController" bundle:nil];
UINavigationController *navi2 = [[UINavigationController alloc] initWithRootViewController:viewController2];
[localcontrollerarray addObject:navi2];
self.tabBarController.viewControllers = localcontrollerarray;
[self.window addSubview:self.tabBarController.view];
}
use this type of method in AppDelegate.m and property-synthesize UITabBarController and store array of viewcontroller in it also in application didFinishLaunchingWithOptions method just assign navigationViewController as a RootViewController like bellow..
RootViewController *masterViewController = [[[RootViewController alloc] initWithNibName:#"RootViewController" bundle:nil] autorelease];
self.navigationController = [[[UINavigationController alloc] initWithRootViewController:masterViewController] autorelease];
after then when you want to add TabBar to any view at that time call this bellow method like this..
[appDelegate addTabBarControllerInwindow];
-(void)addTabBarControllerInwindow
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.window cache:YES];
[self.navigationController.view removeFromSuperview];
[self.window addSubview:[tabBarController view]];//tabBarController.view
[UIView commitAnimations];
}
Create an Application using Tab Bar Controller and on the ViewDidLoad method of the view controller for which you want to hide the tab bar use code:
[self.tabBarController.tabBar setHidden:YES];
And don't forget to unhide the tab bar using the same code replacing NO instead of YES for the view controller for which you want to show the tab bar.

Unable to present modal view controller in didFinishWithResult

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];
}];
}

hide UITabBarController's tab bar when pushing UIViewController

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];

Switching from a normal view to a TabBar Controller

I build my first iPhone application and I have a problem with switching views.
First, I have two views (login, registration) which switch via "presentModalViewController:animated:".
But if someone logged in, there must be a new kind of view. I wanna have an UITabBar at the bottom (tab bar controller). But this does not work. I tried to create a new AppDelegate, so that I can use tutorials like this one which need a AppDelegate:
http://www.youtube.com/watch?v=LBnPfAtswgw&feature=player_embedded
The switch to the new controller is done like this:
startViewController = [[StartViewController alloc] initWithNibName:#"StartView" bundle:nil];
[UIView beginAnimations:#"View Curl" context:nil];
[UIView setAnimationDuration:2.0];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.view cache:YES];
[self.view addSubview:startViewController.view];
[UIView commitAnimations];
The screen is white, because the shown view is the UIView in my StartView.xib. There I have the new AppDelegate, File's owner, View, TabBarController. But only the UIView is loaded and not the TabBarController.
Do you have an idea how I could this problem?
Thanks & Best Regards.
I might suggest you start with a TabBarController, and if the username/password is not set, the active ViewController executes presentModalViewController:animated: to display the login/registration viewsControllers in modal mode (hidding the underliying TabBarController).
Here is some sample code for doing it programmatically.
- (void)applicationDidFinishLaunching:(UIApplication *)application {
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
[window setBackgroundColor:[UIColor whiteColor]];
tabBarController = [[UITabBarController alloc] init];
aViewController = [[aViewController alloc] init];
UINavigationController *aNavController = [[[UINavigationController alloc] initWithRootViewController:aViewController] autorelease];
aNavController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
[aViewController release];
tabBarController.viewControllers = [NSArray arrayWithObjects: aNavController, nil];
// Add the tab bar controller's current view as a subview of the window
[window addSubview:tabBarController.view];
if(userNotLoggedIn){
[self displayLoginViewController];
}
[window makeKeyAndVisible];
}
- (void)displayLoginViewController {
LoginViewController *controller = [[LoginViewController alloc] init];
// setup controller
[self.tabBarController presentModalViewController:controller animated:NO];
[controller release];
}