What is the better code to move from "page" to "page"?I have a questionnaire on 4 pages and I loading 4 views from 4 xibs.
I picked up 2 way of moving from xib to xib (in my case, from page to page).
Method 1:
-(IBAction) MaleTapped: (id) sender {
Page1M *ivc = [[Page1M alloc] init];
UINavigationController *nc = [[UINavigationController alloc]
initWithRootViewController:ivc];
[self presentModalViewController:nc animated:NO];
[ivc release];
[nc release];
}
Second way:
-(IBAction)GotoPage2M:(id)sender {
page2M = [ [Page2M alloc]
initWithNibName:#"Page2M" bundle:nil];
[self.view addSubview:page2M.view];}
One method uses the RootViewController method, the second just loads the subview. For my 4 pages, which is the better/cleaner/smarter way?
I would recommend using a UINavigationViewController in this way. Going several modal views deep is icky.
- (IBAction) goToNextPage:(id)sender {
UIViewController * newView = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
[self.navigationController pushViewController:newView animated:YES];
[newView release];
}
The only reason I might do subviews is for the extra transition options.
I would recommend checking out Apple's sample Page Control code. It shows how to create something that pages through multiple view controllers and load them dynamically from xibs. The example just loads the same xib several times, but you could replace it with code that loads a different view controller or xib for each page.
Related
I don't know if what I'm trying to do is possible, but because I haven't the desired results, I guess not.
What I'm trying and need to do is to call a SplitViewController from a previous ViewController, using presentViewController.
I know, SplitViewController have to be the rootViewController, but I need to explore the most possible options to achieve what I need to do.
I have a MainMenu with buttons, and with every button, I need to call a SplitViewController. First, how can do this?
What I'm trying to do is this:
First, in AppDelegate I'm calling the MainMenu, and add as a subview and other things:
-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[window addSubview:self.mainMenu.view];
[self.mainMenu presentModalViewController:self.firstMenu animated:NO];
[self.window makeKeyAndVisible];
return YES;
}
Then, in the MainMenu, I'm calling SecondViewController, in modal view, using this code:
SecondViewController *secV = [[SecondViewController alloc]initWithNibName:#"SecondViewController" bundle:nil];
secV.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:secV animated:YES];
In this SecondViewController, I'm creating SplitViewController, with Master & DetailViewController's, using this code:
-(void)viewDidLoad{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
UISplitViewController *splitViewController = [[UISplitViewController alloc]init];
SecondMenuViewController *secMenu = [[SecondMenuViewController alloc]init];
UINavigationController *navLef = [[UINavigationController alloc]init];
[navLef pushViewController:secMenu animated:NO];
SecondMainViewController *secMain = [[SecondMainViewController alloc]init];
UINavigationController *navRig = [[UINavigationController alloc]init];
[navRig pushViewController:secMain animated:NO];
splitViewController.delegate = secMain;
splitViewController.viewControllers = [NSArray arrayWithObjects:navLef, navRig, nil];
MainAppDelegate *mainApp = [[MainAppDelegate alloc]init];
[mainApp changeRootViewController:splitViewController];
navRig = nil;
navLef = nil;
secMain = nil;
secMenu = nil;
splitViewController = nil;
}
As you can see, I'm calling a method in MainAppDelegate, to change view and RootViewController, because SplitViewController have to be RootViewController. This is the method:
-(void)changeRootViewController:(UISplitViewController *)splitViewController{
[self.window addSubview:splitViewController.view];
self.window.rootViewController = splitViewController;
}
I know, this looks like a mess. And when I run, the SplitViewController never shows, so I assume, what I'm trying to do is not possible? Or In what I'm wrong?
If it is everything, what can I do to show a SplitViewController after my MainViewController?
I'm using XCode4.4 and iOS5
Thank you very much
A better way would be to make your UISplitViewController the root view controller in application:didFinishLaunchingWithOptions:. Then present your MainMenu on top of it. You can change the subviews displayed by the split view controller to correspond to what button the user pushes in your MainMenu.
First, didFinishLaunchingWithOptions: is too early to be calling presentModalViewController. You haven't even got an interface yet!
Second, you don't seem to have a root view controller (although perhaps you're getting one from a nib? you should probably stop doing that; use the techniques shown in the current application templates).
Third, note that now that we have custom container views, there is no need for you to use UISplitViewController at all; you can construct your own view / view controller hierarchy, and you might be happier doing so, since UISplitViewController is not a very well-constructed class.
I have some uiview, one call another in this way:
From first uiview:
MyViewController *contr1 = [[MyViewController alloc] initWithNibName:#"MyViewController" bundle:nil];
[self.view addSubview:contr1.view];
From second uiview:
MyViewController2 *contr2 = [[MyViewController2 alloc] initWithNibName:#"MyViewController2" bundle:nil];
[self.view addSubview:contr2.view];
now in the third uiview i want to return back on the first updating it ( calling viewDidLoad ). how can i do?
First of all - you are doing it wrong.
Since you are using view controllers present them modally or push them:
MyViewController2 *contr2 = [[MyViewController2 alloc] initWithNibName:#"MyViewController2" bundle:nil];
[self presentModalViewController:contr2];
If you want to dismiss modal controllers exactly to your root view controller you should obtain a pointer to it in the controller you are currently using and send it a message to dismiss every modal view that there is on it.
- (IBAction)doHomePage:(id)sender {
MyAppDelegate *appDelegate = (MyAppDelegate *)[UIApplication sharedApplication].delegate;
[appDelegate.navigationController.rootViewController dismissModalViewControllerAnimated:YES];
}
Also instead of viewDidLoad: you might want to use viewWillAppear: or viewDidAppear:.
Sorry beforehand if there are some typo errors in the code since I wrote it by hand.
How would I make this code animate in the SplashView NIB instead of just making it appear (e.g. the UIModalTransitionStyleFlipHorizontal style)? I am using a UITabBarController type project.
- (IBAction)showSplash:(id)sender {
// Hide toolbar
self.tabBarController.tabBar.hidden = YES;
// Splash
[[NSBundle mainBundle] loadNibNamed: #"SplashView" owner: self options: nil];
[self.view addSubview: splashView];
[window makeKeyAndVisible];
}
Bit hard to tell your context with this small bit of code. Basically, if you want to push a viewController modally, in your -(IBAction)showSplash method (you don't need to send the sender if you're not using it, BTW), I would use some code similar to this:
SplashViewController *svc = [[SplashViewController alloc] init]; (assuming nib is same name)
self.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
[self presentModalViewController:svc animated:YES];
[svc release];
Then in your SplashViewController you would have an IBAction that calls:
[self dismissModalViewController animated:YES];
You don't actually have to hide the tabBar when you are presenting a modalViewController. It won't be there. The idea of a modalViewController is that it blocks all user interaction with the app except for the modal view, until it is dealt with.
Hope this helps.
I'm trying to do very simple example of a UINavigationController. Here is my code:
- (void)viewDidLoad {
[super viewDidLoad];
This next line works, or at least doesn't blow up.
navController = [[UINavigationController alloc] initWithRootViewController:self];
self.title = #"blah";
PageOneController *one = [[[PageOneController alloc]init] autorelease];
Example 1. THIS LINE DOES NOTHING
[navController pushViewController:one animated:NO];
Example 2. THIS LINE WORKS (but no nav controller, of course)
[self.view addSubview:one.view];
}
Why am I unable to push ViewController instances onto the navController and see the screen change?
Note: I realize that I might have my concepts backwards and I don't need to have my view referencing a UINavigationController... or something.
- (void)viewDidLoad {
[super viewDidLoad];
PageOneController *one = [[[PageOneController alloc]init] autorelease];
one.title = #"blah";
navController = [[UINavigationController alloc] initWithRootViewController:one];
[self.view addSubview:navController.view];
}
The basic idea behind it is that a navigation controller's root view controller is the controller which view will be displayed first in the navigation controller hierarchy. The root controller is not the view controller that you plug the navigation controller into. Hope this helps.
I'm just restating #E-ploko's answer, which is 100% correct (which is why I marked it best answer).
You need more views (and view controllers) to use the UINavigationController. One of them houses the UINavigationController, and its rootViewController is the first page of the series (the one that has no "back").
I got rid of the external dependencies for the code sample: obviously this is monolithic sample code, not monolithic real code.
- (void)viewDidLoad {
[super viewDidLoad];
UIViewController *one = [[UIViewController alloc] init];
[one.view setBackgroundColor:[UIColor yellowColor]];
[one setTitle:#"One"];
navController = [[UINavigationController alloc] initWithRootViewController:one];
// here 's the key to the whole thing: we're adding the navController's view to the
// self.view, NOT the one.view! So one would be the home page of the app (or something)
[self.view addSubview:navController.view];
// one gets reassigned. Not my clearest example ;)
one = [[UIViewController alloc] init];
[one.view setBackgroundColor:[UIColor blueColor]];
[one setTitle:#"Two"];
// subsequent views get pushed, pulled, prodded, etc.
[navController pushViewController:one animated:YES];
}
I am new at Objective C. I am just trying to build an iphone app. I have created some NIB file, and i have gone to other NIB file by creating an object and using this code:
scoreViewController *sviewController = [[scoreViewController alloc] initWithNibName:#"scoreViewController" bundle:nil];
self.scoreView = sviewController;
[sviewController release];
// Setup the animation
[self.navigationController pushViewController:self.scoreView animated:YES];
Now I want to come back to the same page. For this case I have done the same work, but it does not work when I add the previous page header file name.
mainViewController *mainviewController = [[mainViewController alloc] initWithNibName:#"mainViewController" bundle:nil];
self.mcoreView = mainviewController;
[mainviewController release];
// Setup the animation
[self.navigationController pushViewController:self.mcoreView animated:YES];
So, I will be most grateful if you were so nice to post your comment.
I am not 100% sure what you are asking, but I think you want to go back from the the second controller to the first. What you are doing here is instantiating a second instance of the first controller (so you now have 3 controllers), and pushing it onto the stack. Assuming I have this correct, then if you want to move back to the first controller you should be popping the second controller off the stack, not adding a 3rd:
//mainViewController *mainviewController = [[mainViewController alloc] initWithNibName:#"mainViewController" bundle:nil];
//self.mcoreView = mainviewController;
//[mainviewController release];
// Setup the animation
[self.navigationController popViewControllerAnimated:YES];