I'm trying to build an app that have main view at the beginning with 3 buttons, then when the user press any button of these buttons, the tab bar view will appear with selected tab bar item.
My problem is here, when the tab bar view should appear ... it appears empty !!
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
MainMenuViewController *mainMenuViewController = [[[MainMenuViewController alloc] initWithNibName:#"MainMenuViewController" bundle:nil] autorelease];
self.navigationController = [[[UINavigationController alloc] initWithRootViewController:mainMenuViewController] autorelease];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
//Button Action in main menu view
-
(IBAction)button1Action:(id)sender {
TabbarViewController *tempView = [[TabbarViewController alloc] initWithNibName:#"TabbarViewController" bundle:nil];
[self.navigationController pushViewController:tempView animated:YES];
[tempView release];
}
You have to set viewControllers property of your TabbarViewController(of course if it is superclass of UITabBarController). Create your 3 viewControllers in init method of TabbarViewController, add them to array and set it as viewControllers property like this:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
NSLog(#"%#",[[self class] superclass]);
UIViewController *yourFirstViewController = [[UIViewController alloc] init];
UIViewController *yourSecondViewController = [[UIViewController alloc] init];
UIViewController *yourThirdViewController = [[UIViewController alloc] init];
yourFirstViewController.title = #"First";
yourSecondViewController.title = #"Second";
yourThirdViewController.title = #"Third";
NSArray *threeViewControllers = [[NSArray alloc]initWithObjects:yourFirstViewController, yourSecondViewController, yourThirdViewController, nil];
self.viewControllers = threeViewControllers;
// Custom initialization
}
return self;
}
Related
I have an old project that has it's view implemented as xibs. The views are controller with a tabbar.
Now I want to add a new UITabBarItem, but I want that this new item is not xib-based, but Storyboard based. Meaning, I want to use a storyboard just for the content of this tabbar item, and leave the rest of the app as it is.
I did the following:
created the new storyboard
created a new ViewController that should be the wrapper for the storyboard
then I changed the underlying VC in IB of the Tab to the new VC
But how to I proceed now? I tried this to make the InitialViewController the ViewCOntroller of the the Tab:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
UIStoryboard *financeStoryboard = [UIStoryboard storyboardWithName:#"WS_Finanzierung_Storyboard_iPhone" bundle:nil];
UIViewController * initialViewController = [financeStoryboard instantiateInitialViewController];
[self presentViewController:initialViewController animated:YES completion:nil];
}
return self;
}
But it doesn't work (crashes yet..).
Q: is that the right way to do it anyway? Is there a best practice doing this?
Thanks in advance
Try this one..
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
UIViewController *viewController1 = [[FirstViewController alloc] initWithNibName:#"FirstViewController" bundle:nil];
UIViewController *viewController2 = [[SecondViewController alloc] initWithNibName:#"SecondViewController" bundle:nil];
UIViewController *viewController3 = [[StoryViewController alloc] init];
UIStoryboard *tableViewStoryboard = [UIStoryboard storyboardWithName:#"Storyboard" bundle:nil];
viewController3 = [tableViewStoryboard instantiateViewControllerWithIdentifier:#"newTab"];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[viewController1, viewController2, viewController3];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
Assign storyboard identifier like this -->
and uncheck is initial view controller -->
Output ll be like this..
I want to change the rootViewController after the authenticationViewController
-(IBAction)LoginButtonPushed:(id)sender {
if ([(VerifyId)isEqual:#"C"]){
CondidatsViewController *condidatsViewController = [[[CondidatsViewController alloc]initWithNibName:#"CondidatsViewController" bundle:nil]autorelease];
UINavigationController *navController = self.navigationController;
NSMutableArray *controllers = [[self.navigationController.viewControllers mutableCopy] autorelease];
[controllers removeLastObject];
navController.viewControllers = controllers;
[navController pushViewController:condidatsViewController animated: YES];
} else {
RecruteursViewController *recruteursViewController = [[[RecruteursViewController alloc]initWithNibName:#"RecruteursViewController" bundle:nil]autorelease];
UINavigationController *navController = self.navigationController;
NSMutableArray *controllers = [[self.navigationController.viewControllers mutableCopy] autorelease];
[controllers removeLastObject];
navController.viewControllers = controllers;
[navController pushViewController:recruteursViewController animated: YES];
}
}
this code is when i press in login button i want CondidatsViewController or RecruteursViewController will be the rootView
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
// Override point for customization after application launch.
AcceuilViewController *viewController =[[[AcceuilViewController alloc]
initWithNibName:#"AcceuilViewController" bundle:nil]autorelease];
self.navController = [[[UINavigationController alloc]initWithRootViewController:viewController]
autorelease];
self.window.rootViewController = self.navController;
[self.window makeKeyAndVisible];
return YES;
}
You can try UINavigationController's following method with a new array of desired view controllers something like
[self.navigationController setViewControllers:#[newRootViewControllerInstance, secondVCInstanceIfRequired, thirdVC-and-so-on....] animated:NO];
It will do the trick ;)
How about have a view controller one level above your nav and auth view controllers? This view controller can check for a valid session and push whatever view is appropriate on top of the stack. It seems ill advised to try to change your root view controller.
Edit: More details
You have a root view controller that doesn't have a view tied to it like most other view controllers might. You set this class as the root view controller in your app delegate.
App Delegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
RootViewController *rootViewController = [[RootViewController alloc] init];
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
In your root view controller you can determine if you have a valid session or not. Based on that, you can render the appropriate view.
RootViewController.m
#interface RootViewController ()
#end
#implementation RootViewController
- (void)viewDidLoad
{
[super viewDidLoad];
BOOL isUserAuthenticated = [MyClasskToFigureOutIfUserIsAuthenticated isUserAuthenticated];
if(isUserAuthenticated == NO) {
AuthViewController *vcAuth = [[AuthViewController alloc] init];
[self addChildViewController:vcAuth];
[self.view addSubView:vcAuth.view];
} else {
//they are authenticated so push your other view controller.
}
}
#end
This is pretty rough, but it should point you in the right direction.
I just created a new iPhone tabbed Application using xcode project template, without storyboard. I deleted the FirstViewController and SecondViewController which was generated by the project template.
Later, I created new controllers called MyFirstViewController (subclass of UITableViewController) and MySecondViewController (subclass of UIViewController) and put them under UINavigationControllers
I changed the code a bit so now it looks like below:
appdelegate.m :
#import "MyFirstViewController.h"
#import "MySecondViewController.h"
....
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
//create view controllers
UITableViewController * vc1 = [[MyFirstViewController alloc] initWithNibName:nil bundle:nil];
UIViewController * vc2 = [[MySecondViewController alloc] initWithNibName:nil bundle:nil];
//create navigation controllers
UINavigationController *nav1 = [[UINavigationController alloc] initWithRootViewController:vc1];
UINavigationController *nav2 = [[UINavigationController alloc] initWithRootViewController:vc2];
//add nav controllers to tab bar controller
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = #[nav1, nav2];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
tabBarItem is NOT SHOWING on first tab
MyFirstViewController.m :
- (id)initWithStyle:(UITableViewStyle)style
{
self = [super initWithStyle:style];
if (self) {
// Setting tabbar item and image here is not showing. It just show empty tab, no title and no image. why o why?
self.tabBarItem.image = [UIImage imageNamed:#"someImage"];
self.tabBarItem.title = #"someName";
}
return self;
}
but the second tab is working just well
MySecondViewController.m :
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// This is showing just fine
self.tabBarItem.image = [UIImage imageNamed:#"someImage"];
self.tabBarItem.title = #"someName";
}
return self;
}
Any idea why a subclass of UITableViewController can't show the tabBarItem? meanwhile UIViewController can show it just fine.
In your didFinishLaunchin method you have
UITableViewController * vc1 = [[MyFirstViewController alloc] initWithNibName:nil bundle:nil];
But in your MyFirstViewController you
- (id)initWithStyle:(UITableViewStyle)style;
You need to call this method instead on initWithNibName, as this method doesn't exist your tabBarItem is not showing up.
Excuse if this problem is posted already..
I want to create combination of TabBar and NavigationBar programmatically using XCode 4.2 & iPhone SDK 5.0
It produces visual as expected..but when a TabBarItem is pressed(taped) to change to its corresponding view, it is producing error: [__NSCFString _tabBarItemClicked:]: unrecognized selector sent to instance
Here is the implementation of the AppDelegat
#import "ApplicationDelegat.h"
#import "BrightnessController.h"
#implementation ApplicationDelegat
#synthesize window;
//#synthesize bControl;
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
NSMutableArray *controllers = [NSMutableArray array];
UITabBarController *tbarController = [[UITabBarController alloc] init];
for (int i = 0; i <= 3; i++)
{
//self.bControl = [[BrightnessController alloc] initWithBrightness:i];
BrightnessController *bControl = [[BrightnessController alloc] initWithBrightness:i];
UINavigationController *nav = [[UINavigationController alloc] initWithRootViewController: /*self.bControl*/bControl];
nav.navigationBar.barStyle = UIBarStyleBlackTranslucent;
[controllers addObject: nav];
//bControl.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"test" image:nil tag:i];
//tbarController.navigationController.delegate = self;
}
tbarController.viewControllers = controllers;
tbarController.customizableViewControllers = controllers;
tbarController.selectedIndex = 0;
tbarController.delegate = self;
// NSCFString
//tabBarItem
// Set up the window
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window addSubview:tbarController.view];
[self.window makeKeyAndVisible];
}
#end
I don't know why it happens and how to recover it..
Somebody help me.
If more detail is required, I can provide the source code...
Thanks in advance.
- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController; 7:20
switch(mytabbar.selectedIndex)
{
case 0:
[imageView1 setImage:[UIImage imageNamed:#"Tab1_sel.png"]];
[imageView2 setImage:[UIImage imageNamed:#"Tab2.png"]];
[imageView3 setImage:[UIImage imageNamed:#"Tab3.png"]];
[imageView4 setImage:[UIImage imageNamed:#"Tab4.png"]];
[imageView5 setImage:[UIImage imageNamed:#"Tab5.png"]];
break;
case 1:
you can use this method and change on each tabbar click index
Two issues I see...
You assign the view of the tabBarController as a subView of the window. This is incorrect. You need to set the rootViewController of the window to be the tBarController.
Are you implementing the tab bar's delegate method tabBar:didSelectViewController:? Your error message says you're trying to send a tabBar-related method to an NSString. I suspect it's due in part to point (1). Try:
self.window.rootViewController = self.tBarController;
I typically prefer creating another tabbarview class that handles all the different view controllers, in which case, the app delegate will look like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
ViewController *viewController = [[ViewController alloc] init];
self.window.rootViewController = viewController.myTabBarController;
[self.window makeKeyAndVisible];
return;
}
And in ViewController I do this:
Header file:
#interface ViewController : UIViewController {
IBOutlet UITabBarController *myTabBarController;
}
#property (nonatomic, retain) IBOutlet UITabBarController *myTabBarController;
And in the implementation file:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
exerciseViewController *viewController1 = [[exerciseViewController alloc] init];
viewController1.title = #"Exercise";
viewController1.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Exercise" image:[UIImage imageNamed:#"inbox.png"] tag:0];
UINavigationController *firstNavController = [[UINavigationController alloc]initWithRootViewController:viewController1];
bookViewController *viewController2 = [[bookViewController alloc] init];
viewController2.title = #"Book";
viewController2.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Book" image:[UIImage imageNamed:#"inbox.png"] tag:1];
UINavigationController *secondNavController = [[UINavigationController alloc]initWithRootViewController:viewController2];
askViewController *viewController3 = [[askViewController alloc] init];
viewController3.title = #"Ask";
viewController3.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Ask" image:[UIImage imageNamed:#"inbox.png"] tag:2];
UINavigationController *thirdNavController = [[UINavigationController alloc]initWithRootViewController:viewController3];
workshopViewController *viewController4 = [[workshopViewController alloc] init];
viewController4.title = #"Workshop";
viewController4.tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Workshop" image:[UIImage imageNamed:#"inbox.png"] tag:3];
UINavigationController *fourthNavController = [[UINavigationController alloc]initWithRootViewController:viewController4];
myTabBarController = [[UITabBarController alloc] init];
myTabBarController.viewControllers = [NSArray arrayWithObjects:firstNavController, secondNavController, thirdNavController, fourthNavController, nil];
}
return self;
}
This is just an example...and I think it's the right way to do that.
I am building an app that has a login screen that leads to a tabbar. I followed this example on how to push a modal view once you launch the app (as the "sign in" page) and then dismiss it.
Example --> Show / Hide tab bar
From some reason, it's not really working - when I launch the app, I see the tabbar view with the two view controllers. no sign in page.
here is my code:
AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIViewController *viewController1 = [[FirstTab alloc] initWithNibName:#"FirstTab" bundle:NSBundle.mainBundle];
UIViewController *viewController2 = [[SecondTab alloc] initWithNibName:#"SecondTab" bundle:NSBundle.mainBundle];
UINavigationController *secondNavController = [[UINavigationController alloc]initWithRootViewController:viewController2];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController1, secondNavController, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
My first tab (which is where I understand all this modal view business needs to happen)
.h
#interface FirstTab : UIViewController
#end
.m
//UPDATED CODE PER COMMENT BELOW
- (void)viewDidLoad
{
[super viewDidLoad];
SignIn *loginview = [[SignIn alloc] initWithNibName:#"SignIn" bundle:nil];
UINavigationController *controller = [[UINavigationController alloc] initWithRootViewController: loginview];
self.hidesBottomBarWhenPushed = YES;
[self presentModalViewController:controller animated:YES];
}
And of course, I dismiss the modal view in the SignIn view controller, though I never get there as I mentioned.
What am I doing wrong here? Thanks for the help!!
You could use :
[[self tabBarController] presentModalViewController:controller animated:YES];
since first viewController1 is your first tab, and self.navigationController might be nil.
In your custom view controller subclass called SignIn implement initWithNibName:bundle: instead if init.
-(id)initWithNibName:(NSString *)nibNameOrNil
bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// init here
}
}
Now when init/alloc it call either :
SignIn *loginview = [[SignIn alloc] initWithNibName:#"SignIn" bundle:nil];
if your interface is in a NIB file, or :
SignIn *loginview = [[SignIn alloc] initWithNibName:nil bundle:nil];
if there no NIB.
Also why putting it as a root view controller of any navigation controller ? unless you need to go deeper in some model data presentation, just present it directly :
// why ?
//UINavigationController *controller = [[UINavigationController alloc]
// initWithRootViewController: loginview];
//self.hidesBottomBarWhenPushed = YES;
//[self presentModalViewController:controller animated:YES];
[self presentModalViewController:loginView animated:YES];
You have to include this in your code,
yourModelController =[[Yourmodelcontroller alloc]init];
UINavigationController *controller = [[UINavigationController alloc] initWithRootViewController: yourModelController];
self.hidesBottomBarWhenPushed = YES;
[[self navigationController] presentModalViewController:controller animated:YES];
[controller release];
hope this will help you out.
I've encountered issues where modals don't like showing from viewDidLoad. Try adding your code to your viewWillAppear and it should show.