Navigation based application with an add button - iphone

I created a new Navigation Based Application project.Then in MainWindow.xib I added a button to the navigationbar. I would like to push a new View onto the screen where I can enter information, which will be added as an object to the array of the UITableView.
But I don't know where to write the IBAction to link the button to (Appdelegate or the RootViewController)? Because as you see in the screenshot, it resides in MainWindow.xib because the RootViewController is merely a Table and doesn't contain the navigation. But in the document view of MainWindow.xib it is located under the RootViewController.
Do I have to create a new View Controller inside the XIB as well and create an IBOutlet for it?
I tried putting the code inside my AppDelegate and reference the button to the delegate but it doesn't work.
Please help. Thanks in advance.
See the screenshot here: http://i56.tinypic.com/5djbcm.png

When you ask yourself a question "where does this action belong" it's most probably a controller because controllers handle event flows in your app. Next question - "What controller is in charge when this action happens? What controller is most interested in this action?". Answer in your case is root table controller (RootViewController instance). Create an IBAction method in it which will push form controller (one you use to enter information) to navigation controller.
// somewhere in RootViewController.m
- (IBAction)addNewEntry {
NewEntryFormController *c = [[[NewEntryFormController alloc] init] autorelease];
// ...
[self.navigationController pushViewController:c animated:YES];
}

Related

NavigationController and Modal Views

I am a newbie to iOS world and have started building custom code on top of a templated code.
So excuse me for the obvious.
The View chain starts with a MainWindow.xib which contains a App Delegate Object, a Window Object and Application ViewController. I dont understand why those objects are needed over there. But what I understand, I need to mention starting ViewController in the "Nib Name" Property to initiate my custom View Controller (called "EmptyViewController"). Its a dummy view controller, just there to avoid crash to happen as a result of missing valid viewcontroller.
I initiate a separate Modal View Controller(MainViewController) inside didFinishLaunchingWithOptions.
Code for initiating modal View Controller --
self.window.rootViewController = self.viewController;
mainView = [[MainViewController alloc] initWithNibName:#"MainViewController" bundle:nil];
// present the viewcontroller
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:mainView];
[self.viewController presentModalViewController:navController animated:NO];
// release it, because it's retained as modalViewController
[navController release];
I do not put this MainViewController inside MainWindow.xib as I want to have navigation at the root of MainViewController.
Inside MainViewController, I push HelpViewController when "help" button is pressed.
But HelpViewController does not show any navigation bar. I do not understand why?
Code for Pushing Navigation bar --
HelpViewController *helpVC = [[HelpViewController alloc] init];
[self.navigationController pushViewController:helpVC animated:YES];
[helpVC release];
So I would like to understand --
1) Why is MainWindow.xib needed? Can I remove it? (Note: I tried to remove it, but then I get blank screen)
1.a) Why are all the controls/objects App Delegate Object, a Window Object and Application ViewController objects needed?
2) Why doesnt HelpViewController show Navigation bar?
3) Another thing I noticed, if I say self.presentingViewController, EmptyViewController handle is returned while popViewController returns me back to MainViewController.
Thanks
The App Delegate simply implements some app-level 'callbacks' by which iOS communicates with your own code. In main.m you can see how iOS is told which of your classes implements UIApplicationDelegate. iOS creates an instance of this class and call these delegate methods ('callback') whenever appropriate (e.g. when the app goes to background).
The Window is something iOS provides, your app needs to tell what to display on it. And, as you saw, this is usually done in didFinishLaunchingWithOptions (which is called by iOS to inform your app things are ready to get started).
A View Controller is a class that handles states of stuff you show on the Window. You don't show stuff directly on the Window, but instead use Views. Every View Controller has a View with UI elements.
The XIB or NIB is a UI description/layout file. A XIB and View are linked together; you need to tell the XIB to which View Controller member (e.g. a UILabel) a UI element belongs, and you tell the XIB which View Controller method to call on a certain UI event (e.g. user taps on a button).
These are the basics. I'm aware it does not answer all your questions; I suggest you read the very good Apple documentation. Don't try to understand everything immediately as things, as you're experiencing, indeed can seem illogical at start.

Creating a TabBarControllerDelegate in a Storyboard

I'm having difficulty creating a UITabBarControllerDelegate in my Storyboard driven iOS5 application. Here is the situation:
I have an initial screen that will eventually handle login but which currently just has a button that sends the user to...
...a Tab Bar Controller with five tabs. Each of these tabs go to...
...a Navigation Controller with many child View Controllers under the root.
(If it helps, a screenshot of the relevant Storyboard section is here.)
When the user switches tabs, I always want the user to be directed to the Root View Controller for that particular Navigation Controller, and not the most recently visited View Controller (which is the default behavior).
I understand that to do so, I need to call popToRootViewControllerAnimated when a Tab is pressed as discussed here and here, but I can't figure out how to do that within the storyboard. How can I do this without scrapping the storyboard and starting over?
Thanks!
There are more than one solutions to your problem (its a matter of design pattern decision). Some of them could be:
Subclass UITabBarController and set it as the custom class of your tabbar in your storyboard (also connect the delegate to your object in order to be handled) and override the -tabBarController:didSelectViewController: delegate method
Pop to the root by calling -popToRootViewControllerAnimated from the viewWillDisappear event of every view that you want this behavior implemented
You can create your own TabBarController, implement a method that instantiate your view controllers
-(UIViewController*) viewControllerWithTabTitle:(NSString*) title
viewController(NSString *)viewController {
UIViewController* returnViewController = [self.storyboard
instantiateViewControllerWithIdentifier:viewController];
return returnViewController;
}
Then in the viewDidLoad method you create the array with the view controllers, that in your case would be the NavigationController's identifier that you set on the InterfaceBuilder.
- (void)viewDidLoad {
self.viewControllers=
[NSArray arrayWithObjects:
[self viewControllerWithTabTitle:#"Option 1" viewController:#"viewController1"],
[self viewControllerWithTabTitle:#"Option 2" viewController:#"viewController2"],
[self viewControllerWithTabTitle:#"Option 3" viewController:#"viewController3"],
[self viewControllerWithTabTitle:#"Option 4" viewController:#"viewController4"],
[self viewControllerWithTabTitle:#"Option 5" viewController:#"viewController5"], nil];
}

Navigate from one view to another using UIButton

I have an application with 2 views . In the first one I have a button which when I clicked the user should go to the second view. I tried what is explained before here from Karoley , but it does not work . When I click the button nothing happened?
Here is the code of my action :
-(IBAction)gotoSecondPage:(id) sender{
NSLog(#"In gotoSecondPage");
LeoActionViewController *aSecondPageController =
[[LeoActionViewController alloc]
initWithNibName:#"LeoActionViewController"
bundle:[NSBundle mainBundle]];
[self.navigationController pushViewController:aSecondPageController animated:YES];
}
LeoActionViewCOntroller is a controler for a second view.
It just do not switch to a second view. I do not know why
I put code your problem this will help you. First of all, you declare method and open .xib file and then connect to that button with selected touchupinside connection.
In the .h file:
- (IBAction)gotoSecondPage:(id) sender;
In the .m file:
- (IBAction)gotoSecondPage:(id) sender
{
NSLog(#"In gotoSecondPage");
LeoActionViewController *aSecondPageController =
[[LeoActionViewController alloc]
initWithNibName:#"LeoActionViewController"
bundle:nil];
[self.navigationController pushViewController:aSecondPageController animated:YES];
[aSecondPageController release];
}
I'm not sure in what capacity you want to switch views.
What immediately comes to mind is that you want a Navigation Controller. This is an object that lets you put view controllers on a stack and push and pop them to show and hide them. It creates a navigation pathway through your app and is easy to use. It also facilitates the 'standard' navigation bar which is found in many iphone apps.
If you just want to change one view for another view you can do many things including hiding and showing different views using setHidden:(bool)hidden. Otherwise you can use addSubview:(UIView *)view and removeFromSuperview to add and remove views completely from the superview.

Show login view controller before tab bar controller

I am new to iphone development. I am developing an iphone application which contains four tabs. I have implemented it using tab bar controller. But now i need to show a login screen without tabs before tab bar controller. I have tried so many methods but didnt get the one i wanted.
Can anyone pls explain how to do this with a code snippet??
Create a new class LoginViewController. When your application launches then add the view to the window. Now when login is successful then remove it from superview and add the MainController.
Create a subclass of UITabBarController (though it's not advised by apple), but for this purposes it should be ok and do this in viewWillAppear
- (void)viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
BOOL isLogged in = //do something to determine if you're logged in
if(!loggedIn){
LoginViewController *loginViewController = [[LoginViewController alloc] initWithNibName:#"LoginViewControllerNibHere" bundle:nil];
[self presentModalViewController:loginViewController animated:YES]; //or NO if you don't want it animated
[loginViewController release];
}
}
Or add this to a category for UITabBarController and import it in the app delegate or wherever you're using the UITabBarController
Create a new UIViewController subclass with a nib that represents your login screen (I'll refer to it as SignInViewController).
Open your MainWindow.nib file and add a new UIViewController
Set the new UIViewController's class type to SignInViewController
Set the UIWindow's rootViewController outlet to the new SignInViewController
Now create a new nib file and copy your existing UITabBarController to it (it's best to split nibs rather than having a single-mega nib)
Back in your MainWindow.xib change the existing UITabBarController's attributes to specify the nib name that you just created
Check this Link's source code,
it uses Login Controller as modal view with 4 tabs
http://code.google.com/p/tweetero/source/checkout
Also i tried this way ,
in my first tab view - in viewDidAppear - i'll check Login = YES then
show the LoginController
- [self.tabbarcontroller presentMOdalViewcontroller:LoginView animated:YES];
so every time u click on first tab - if u need to Login put a flag - check it & show Login View
Hope this Helps.
The best way to do this is to create a new LoginViewController as other people have mentioned and then set your rootviewController to tabBarcontroller as soon as you authenticate the user. Here is how you can do this in swift, this is snippet to put as soon you authenticate your user in LoginViewController
let tabBarController = self.storyboard?.instantiateViewControllerWithIdentifier("TabBarController") as! UITabBarController
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
appDelegate.window?.rootViewController = tabBarController
Where TabBarController is the storyboard id of your tab bar controller. It could be anything whatever name you have given it.

TabBar Application with a View that has a UIButton on the View to goto another View outside the TabBar

I'm new to iPhone development, and multiple views (xib or nib) are really confusing me. This is what i'm trying to achieve...
using TabBarControllerAppDelegate
Have 5 different TabBar Items and have created 5 different Views thru the TabBarController
The First View has a UIButton that is a Next button that needs to go to another view called View2.XIB.
I setup a new UIViewController which references the View2 and an IBAction for the switchPage, etc but not able to get it to do anything when clicking on the button.
All of My TabBar buttons work but not able to Navigate to anything outside of the Tabbar
Any help in this regard will be highly appreciated. Anyone have any examples
IBAction switchPageButtonPressed:(id)sender
{
[self.tabbarcontroller.tabBar setSelectedItem:[self.tabbarcontroller.tabBar.items objectAtIndex:1]];
here 1 means ur 2nd tabbar
}
It is difficult to find the problem without the code, but I will assume your action code for the switchPage button is incorrect. You should use code similar to the following:
- IBAction switchPageButtonPressed:(id)sender
{
ViewController2 *view2VC = [[ViewController2 alloc] initWithNibName:#"View2" bundle:nil];
[self presentModalViewController:nview2VC animated:YES];
[view2VC release];
}
If you are confident your method works, then you will want to verify that the action is hooked up correctly. The easiest way to do this is to place a breakpoint on the method and run the app in Debug. When you click the button, the debugger should break on your method, if it doesn't, you will need to check your connections in Interface Builder.