What is the difference between addChildViewController and presentModelViewController - ios

I know there are three ways to change the view in iOS
1.
[self addChildViewController:thirdViewController];
[contentView addSubview:thirdViewController.view];
2.
First * sVC = [[First alloc] initWithNibName:#"First" bundle:[NSBundle mainBundle]];
[self presentModalViewController:sVC animated:YES];
3.
MyViewController *sampleViewController = [[[MyViewController alloc]initWithXXX] autorelease];
[self.navigationController pushViewController: sampleViewController animated:true];
pushViewController requires the navigation controller, which I understand. However, when to use addChildViewController and presentModalViewController??

These are four totally different implementations
addChildViewController is used in iOS5 to do viewController containment, this will enable you to easily create your own NavigationCotrollers or TabControllers its only available in iOS5
addSubview is the lowest level of the three, this will just add a view to another view, as a child
presentModalViewController is used to present a viewController modally on the screen, hence overwriting the old one
pushViewController used in UINavigationController to push a new ViewController to the viewcontrollers stack,

1) was introduced in iOS 5 as part of Apple's paradigm shift to allow view controller hierarchies, it just puts a view controller in front of the current one. You have to manage the flow of controllers.
2) Is the same as one, except it can only be done for one view controller at a time. Actually, this method has been superseded by [self presentViewController:animated:completion:]
3) Adds the view controller to a list so you can go back to the previous one after hitting 'back'. iOS will manage the flow of controllers for you.

Related

How to use Modal View Controllers correctly?

I have a tabbed Iphone project in which I am attempting to present one modal segue but from multiple different view controllers.
Essentially I want it to function the same way the stock music app works in IOS 9 for iphone. You can be in any one different tab and still be able to view the account page.
Demonstration
First problem/question.
How to mimic this behavior without making a ton of segues. Currently I have 3 separate views that I want to call a modal segue from but how can I achieve this without making duplicate segues
Second problem/question.
How to dismiss the modal view without it becoming a deprecated segue. I have found tuts on how to do this but they require another segue back to the "sender" view controller.
If only apple could provide some decent sample code to aid my efforts in my attempt to do this...
you can present and dissmiss any view controller object without segue like below,
UIViewController *vc = [[UIViewController alloc]init]; // your view controller here
// You can present VC like
[self presentViewController:vc animated:YES completion:^{
// do your task on completion
}];
// In your Presented VC you can dissmiss it like
[self dismissViewControllerAnimated:YES completion:^{
//do your task on completion
}];
Update as per comment :
You can instantiate story board like,
SideMenuViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:#"sideMenu"];
Here SideMenuViewController is custom viewController class set to viewcontroller from storyboard.
And make sure you have set storyboard Id under identity from identity inspector. Here my sideMenu is storyboard Identity!
So you can instantiate your storyboard viewcontroller like this and then present it as mentioned before
Hope this will help :)

Which is the recommended way to segue from one view controller to another?

I like to segue from the current view controller to the "settings" view controller. Which method is more efficient to transition and why? Thanks! I have to segue in code because I have to observe a condition at run time.
Method 1:
UINavigationController *navigationController = (UINavigationController *)[[[UIApplication sharedApplication] delegate] window].rootViewController;
SettingsViewController *v = [self.storyboard instantiateViewControllerWithIdentifier:#"settings"];
[navigationController pushViewController:v animated:YES];
Method 2: In the storyboard, control-drag the current view controller icon (bottom left) to "settings" view controller and then name the segue identifier "gotoSettingsVC", set style to "push" and then use this code...
[self performSegueWithIdentifier:#"gotoSettingsVC" sender:nil];
Both work just fine.
If you're using storyboards, segues are probably the better way to go. Instantiate the initial view controller and let the segues be your guide.
Also, while Method 1 can be used with storyboards, unlike segues, it also can be used with regular xibs (or no interface builder at all) as well.
Other than that, it comes down to preference. Some people hate the interface builder and others swear by it. ;)

How to structure an app when using UINavigationController as the window's root view

I'm starting to learn iOS development and am attempting to use UINavigationController as my window's root view. All is working well but I need some advice on how to structure my app. I read the docs and some questions on here too.
Since the navigation controller is managing all my other content view controllers, then all of these view controllers need a way to send messages to the navigation controller. Right? So, I've thought about making a singleton navigation controller that any other view controller can call on to push new view controllers on it. Or, if each view controller has a reference to the navigation controller then they can push/pop easily as well. This is the part I'm not sure about.
Also, for having buttons and actions I have been setting the target as the navigation controller and from there it can handle it correctly and push or pop on it's own. I did subclass UINavigationController for this. And I have my view controllers as references in it. However I ran into an issue where my UITableViewController was handling a selection of a row and I need to push a new view controller on top, but how do I get the reference to the navigation controller?
I hope that makes sense, and any advice on how to structure this would be very appreciated.
Thanks!
I think you're overthinking this. View controllers have a navigationController property built in allowing you to reference the navigation controller. That being said, pushing to a new view controller from within a view controller that is embedded in a navigation controller is as easy as:
UIViewController *myNewViewController = [[UIViewController alloc] init];
[self.navigationController pushViewController:myNewViewController animated:YES];
According to your requirement you need to write like this :-
UIViewController *myNewViewController =
[[[UIViewController alloc]
initWithNibName:#"yourNibName"]
bundle:nil]];
[self.navigationController
pushViewController:myNewViewController
animated:YES];
This will push one controller on the bottom of the stack.

Dismiss one modal view controller after showing another

I've done a bit of research and read other answers I found here but haven't found anything that actually works. I have an app that when something is posted I want to go to the post and if the back button is pressed when viewing the post it should go back two views basically skip over the compose view.
Below is what I've tried but it gives
Warning: Attempt to present on whose view is not in the window hierarchy!
-(IBAction)post{
[[self presentingViewController] dismissModalViewControllerAnimated:NO];
}
-(void)viewDidDisappear:(BOOL)animated{
[super viewDidDisappear:animated];
ViewPostViewController *dvController = [[ViewPostViewController alloc] initWithNibName:#"ViewPostViewController" bundle:[NSBundle mainBundle]];
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:dvController];
nc.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:nc animated:NO];
[nc release];
}
If you trying to create a hierarchy of views like this, you should probably be using these:
[self.navigationController pushViewController:ViewController animated:BOOL completion:nil];
[self.navigationController popViewControllerAnimated:BOOL completion:nil];
Instead of:
[self presentViewController:ViewController animated:BOOL completion:nil];
[self dimissViewControllerAnimated:BOOL completion:nil];
PresentViewController is usually used to show a single view controller then dismiss it, not generally when you want to show several view controllers in a chain, then work your way back up the chain.
The former is advisable because it uses the stack concept to push and pop view controllers. So you can start with your initial list set up as the root view controller, push on your post compose view, then push on the third view to go to posting. Then when you want to go back to the first view controller by popping off two view controllers, you can use:
[self popToRootViewControllerAnimated:BOOL completion:nil];
You might find the UINavigationController reference useful.
Good luck.
If you want to present a view controller right after another modal view controller has animated out then you have to delay it because otherwise the new one will not appear.
before iOS 5 you would do a performSelectorAfterDelay: with something like 0.25 sec. For iOS 5 and above you wouldn't use modelViewController methods any more as those have been deprecated. Instead you use the presentViewController methods which give you an completion block that is called when the animation is done.
I'm a little confused about what you're trying to do. If you're using a navigation controller, you should be doing pushes and pops, not presenting and dismissing. If you want to use navigation controllers, then you can use popToViewController:animated: to go back to any particular controller without passing through the ones in between. You would have to create a custom back button, though, or do it in code, because the standard back button will only take you back to the previous view controller.

Moving from one view to another iOS

I'm relatively new to iOS development. I am to move from one viewController to another I use a modal segue transition on button click. This is a game so i want to allow the user to click images to essential move the the app menus.
I have a main page that displays several images, on clicking one i want to be able to move to another view. Currently doing this with a modal segue is causing odd problems with my touchesEnded event where if, for example, i navigate to a page 3 times the touchesEnded event is fired 3 times.
Is there a better way for me to do this or am i just missing thing fundamental?
Thanks
Yes, I think you must make the the navigation controller your root view controller then push views accordingly
UINavigationController * nav = [[UINavigationController alloc] initWithRootViewController:YOUR_BASE_CONTROLLER]
self.rootViewController = nav;
this is in your app delegate.
Then in your action method
[self.navigationController pushViewController:secondViewController animated:YES]
Im assuming you are using the Storyboard to link VCs using segues.
Modal segues are great for simple transitions but really seem to limit what you can accomplish when they are just linked through SB. Ive found that creating an IBAction that includes the following for a VC segue will allow you to not only control your segues more efficiently but also allow you to have a clearer view of what is actually occurring during the transition.
-(IBAction)goToVc:(id)sender{
//Other code to take place during the segue here
//This will identify the Storyboard in use
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
//This will identify the View Controller to switch to
SecondViewController *vc2 = [storyboard instantiateViewControllerWithIdentifier:#"SecondViewControllerID" ];
[self presentViewController:vc2 animated:YES completion:NULL];
}
Every time you perform a modal segue, you lose the UINavigationController that you were previously using. What you need to do is embed a UINavigationController in the view that you are performing a modal segue to.
Check out a question I answered the other day to help you visualize more clearly what I'm talking about.

Resources