I started my application as a navigation based application, and did the main bulk of the work using the tables etc. Now, I wish to create a start view page, consisting of two buttons, one which links to the RootViewController and the other which links to another view.
Is this possible? If so, how would I go about it?
Thanks!
Make a new UINavigationController with your startview as the rootViewController for the window first.
Then on the click event of the first button, make a delegate call to your appDelegate class and remove the present UINavigationController and add the main UINavigationController (which links to your RootViewController) as the rootViewController for the window.
For the second buttons click event you can simply push the next view to the navigationController.
Related
How do I get a reference to the UINavigationController's backBarButtonItem from the UINavigationController at the top of the stack. In some circumstances I want to disable going back until some networking code is complete.
self.parentViewController.navigationItem.backBarButtonItem.target =
self;
self.parentViewController.navigationItem.backBarButtonItem.action =
#sel...;
doesn't work
delegate method
- (BOOL)navigationBar:(UINavigationBar *)navigationBar
shouldPopItem:(UINavigationItem *)item
doesn't work either.
An answer and a recommendation:
The answer: I would recommend you change your MVC model slightly to have a BOOL property in your model that is on or off depending on whether the network activity is done and then use a delegate/protocol adopted by your QuestionsVC that updates the back button setting as that property changes. You would need to add the following in the delegate method in QuestionsVC:
[self.tabBarController.navigationItem setHidesBackButton:YES animated:YES];
I tested it and it works.
The recommendation: It is never recommended to have UITabBarController inside a UINavigationController (only the inverse is recommended). I would adjust accordingly before you get too deep into your project.
Update:
I can understand the need for a mainVC as startup VC with a button to "start" if you will. You are correct that you need a NavController to be able to push/pop VCs and use segues in Storyboard. But that is not the only way to display a sequence of VCs, you can present/dismiss VCs. So in your case:
1- I would delete the first NavController
2- Make the MainVC the starting VC (entry point) by moving the arrow on the left of the NavController to the left of MainVC
3- Disconnect Main VC from TabBar controller (delete that link) because you will not be able to use segues in SB without Nav Controller. You will have to instantiate and present that tab bar Controller.
4- Add a new object file (.m/.h) - a subclass of UITabBarController and change the class of the tabBarController in IB to the name of your subclass. You might have to build/clean or restart xcode if it does not show on the dropdown of the class list in IB.
5- Create an IBAction method in your mainVC and link it to the button in Main VC.
6- In that method (in your Main VC), add the following code:
yourTabBarControllerSubClassName* myTabController= [self.storyboard instantiateViewControllerWithIdentifier:#"theTab"];
[self presentViewController:myTabController animated:YES completion:nil];
7- Make sure that in your SB that you select the tab bar controller and in the identity inspector, put the SB ID as "theTab" and check "use SB ID".
8- if questions VC or status table VC have a sequence of VCs within each, you can embed each VC in a Nav Controller and that would be ok.
With that the case, you might not need to worry about that back button since it won't exist anymore!
Good luck
Hope this helps.
As the title suggests, I have built an utility based app.
The app consists (at the moment) of 2 view controllers + a model class hierarchy.
The thing is , as I'd like to add some features to the app , I would like to convert it to a TabBar based application.
As a first step , I would like the first view to be the first view of the tab bar , and the flipSideView to be one of the other tab bar items.
Is there any "standard procedure" / "grocery list" for such tasks ?
I'm sure some of you have encountered the same problem , and would love some advice on "slicing up" the app , and "wiring it up" after creating a new nib file for the main window (is that the first step ? )
Thanks in advance.
I would probably start as follows (assuming you are using Interface Builder and using the standard Xcode utility app template):
Edit your MainWindow.xib file and drag a Tab Bar Controller object into the top level of your view hierarchy.
The default tab bar controller in IB includes two view controller items as examples. Click the first one and change its class to be your existing Main View Controller class.
You can also set the icon and tab bar title for the main view controller item by adding the associated Tab Bar Item that IB has already added to the view hierarchy.
Do the same for the second tab bar item setting the class for the FlipsideViewController.
Delete the old version of your Main View Controller from the NIB file and also remove the IBOutlet property from the Application Delegate (you probably also have references to the main view controller in dealloc which should be removed).
In your App Delegate add an IBOutlet property for the Tab Bar Controller as follows (don't forget to synthesise the property):
#property (nonatomic,retain) IBOutlet UITabBarController *tabBarController;
In IB wire up the tabBarController outlet from the App delegate object to the Tab Bar Controller object.
Finally to get the tab bar controller to show up in place of the main view controller change the code in application:didFinishLaunchingWithOptions: to the following:
[self.window addSubview:self.tabBarController.view];
This should get the basic tab bar app up and running and you can add additional view controllers to the tab bar.
Since you no longer want to flip between the MainView and FlipsideView you can remove the references to the FlipsideViewControllerDelegate from the MainViewController along with the info button and its IBAction method showInfo. Likewise in the FlipeSideViewController you should remove the done button from the view and its IBAction method as these no longer make sense when used with the tab bar.
so, step by step :):
1. declare UITabController outlet in your app delegate.
2. in MainWindow.xib: first drag the instance of UITabBarController in document window, then make connection from app delegate to that instance. now you can set MainViewController as UiTabBarController's first tab viewcontroller, then set FlipsideViewController as UiTabBarController's second tab viewcontroller.
3. in app delegate's appDidFinishLaunching replace [self.window addSubview:mainViewController.view]; with [self.window addSubview:theNameOfUITabBarControllerOutlet.view];. that will do the work. sorry, I don't know your background, that's why I'm not very specific about performing a particular action I decribe, so let me know if you find yourself stuck
I'm new to iPhone development (except developing with cocos2d).
I want to create a simple application that have one window with a button. When i press the button i want some other window to be shown.
Where can i read how do such things?
Also i don't understand well what is View, ViewController, Window. I've read the your first iOS app example.
Look for tutorials on UINavigationController, like this one.
For the meaning of view and view controller you certainly want to read the apple references or in wikipedia. The topic there would be MVC Pattern.
As to your concrete problem:
There is usually only one window in iPhone apps so you certainly want to have a button on a view and if you push that button that view disappears and instead a new view is shown.
You accomplish that by removing the view with the button from its superview ( have a look at the topic tree hierarchy ) and then add the view you want to bee shown as a subview to the main window .
Bottom line is there is one main window and you put views onto it by it's addSubview method. And you remove views by calling their removeFromSuperview method
You should to read it again or google it until you'll understand it well.
view is the graphic output, while view controller is what "manage" the behavior of the view in every event.
your function to navigate -
(IBAction) ButtonClicked
{
static YourViewController *viewController=nil;
if(viewController==nil)
viewController=[[YourViewController alloc] initWithNibName:#"YourViewController" bundle:nil];
[self.navigationController pushViewController:viewController animated:YES];
}
I've been reading the Head First iPhone Development book and I understand how to get to a new view from a table but how exactly would I be able to get to a new view or view controller, by just simply pressing a button? Is that even possible?
I mean there are some apps where you click a button, not a table cell and it loads a new view. How exactly is that done? If someone could help out a newbie it would be greatly appreciated!
I think what you're looking for is a modal vew controller. THis presents a modal view like you described on top of everything else. If rootViewController is the view controller that is displaying your current view, and myNewViewController the view controller you want to display modally:
[rootViewController presentModalViewController:myNewViewController animated:YES];
There's plenty of examples of this kind of thing on the net, just search for presentModalViewController
Like bpapa said in the comments, it's hard to be specific without code. However, generally what you want to do is:
Build a navigation controller that contains one original view.
Create a button in your original view using the Interface Builder.
Build a callback method (usually defined with IBAction) that is run when the button is pushed.
In that callback method, create a new view and push it onto the navigation controller the same way you would using a table view cell.
Alternately, if you only want one level of hierarchy, you could use a modal view controller; instead of pushing onto the navigation controller in the last step, just present the modal view controller.
The general answer is that you have an object that manages which view controller loads when.
The most commonly used is the UINavigationController. It is a UIViewController that instead of controlling views, controls other view controllers. It works like a simple stack. You push views you want to display onto the nav's controller stack and when you want them to disappear you pop them off.
A common (though sloppy) way of using a nav is to make it a property of your app delegate. Then anywhere in your app you can references it by:
UINavigationController *nav=[[[UIApplication sharedApplication] delegate] navigationController];
The view controller for the first the user sees is held in the nav's topViewController property. If you want to load a view based on a user action in the topViewController.view, you would have something like this:
- (IBAction) loadNextView:(id) sender{ // Action called by a a UI event such as a button press.
UINavigationController *nav=[[[UIApplication sharedApplication] delegate] navigationController];
UIViewController *nextViewController=...// load from nib, connect with IBOutlet, create programmatically
[nav pushViewController:nextView animated:YES];
}
The first view disappears to be replaced by the next one. To return to the first view, you have a method in the next view controller like so:
- (IBAction) unloadSelf:(id) sender{ // Action called by a a UI event such as a button press.
UINavigationController *nav=[[[UIApplication sharedApplication] delegate] navigationController];
[nav popViewControllerAnimated:YES];
}
... and the nav returns you automatically to the previous view regardless of what that view was.
When you first start out, especially if you use Interface Builder, the structure of the app is largely hidden. Behind the scenes all view controllers and their views exist in a hierarchy of some kind that leads back up to the app delegate. You should train yourself to think in hierarchal terms even if it is not immediately obvious how that hierarchy is constructed.
Here goes stupid question again :(
I am trying to create a sample app that loads UIViewController when the app loads and the view contains a button to load UINavigationViewController.
Now I created a project with "Window-based Application" and added "RootViewController" in the project with .m, .h, and .xib.
Next I added a view and a button in the "RootViewController.xib" file and it runs ok. After that, I added "UIViewController subclass" file naming "NavViewController" with .h, .m and .xib files.
Also I added - (IBAction)buttonPressed:(id)sender function in the "RootViewController" classes to load NavigationViewController.
Here is the code of the "buttonPressed:".
- (IBAction)buttonPressed:(id)sender {
NavViewController *navViewController = [[NavViewController alloc] initWithNibName:#"NavViewController" bundle:nil];
self.navController = navViewController;
[self.view insertSubview:navViewController.view atIndex:0];
[navViewController release];
}
When I "build and go," it runs fine initially until I press the button. When I press button, program terminates it.
What am I doing wrong? Please help...
Thank you.
What are you doing wrong? Designing your app in a non-standard way - you are not supposed to be able to do this - the NavigationController is in charge!
Why would you have a button that then adds a navigation controller? - it goes against the user interface guidelines. I found it hard to get to grips with the interface guidelines to begin with but you really must because it will make your app so much more usable.
If you need a navigation controller then add it to the view to begin with - or create a new view with the navigation controller. Honestly try it out and you will feel the user interface feels much better.
If you really want a button that adds a navigation controller to the window then do the following:
Keep a reference to the AppDelegate in your code
Use this reference and pass in your current view controller to a method called reloadMainViewWithNavBar:(UNViewController*) viewController
This new method should remove the old mainViewController and create a NavigationController
using your viewController as the root view conroller
add the navigation controller view to window view
The navController has no view set in the nib. A UINavigationcontroller needs a root view. In the nib, connect the navigation controller to a another view controller.
In addition to the fix mentioned above, what you really want to do is create the first view controller contained in the navigation controller - but hide the navigation bar until the button press causes it to unhide. You cannot easily add a navigation controller to a view you are in.