Problem: Tabbar Controller + Navigation Controller: Programmatically - iphone

Hello guys,
I trying to make a app with tabbar controller and navigation controller.
But i get some problems... When i try to popViewController on my second view, the app crash.
Some one knows what's going on?
My Delegate:
// -- PranchetaAppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.tabBarController = [[UITabBarController alloc] init];
NSMutableArray *localControllersArray = [[NSMutableArray alloc] initWithCapacity:1];
PlayersViewController* playersViewController = [[PlayersViewController alloc] initWithTabBar];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:playersViewController];
[localControllersArray addObject:self.navigationController];
[self.navigationController release];
self.tabBarController.viewControllers = localControllersArray;
[self.window addSubview:self.tabBarController.view];
[self.window makeKeyAndVisible];
[self.navigationController release];
[localControllersArray release];
return YES;
}
My First View:
// -- PlayersViewsController.m
- (id)initWithTabBar {
if (self)
{
self.title = #"Players";
self.tabBarItem.image = [UIImage imageNamed:#"PlayersTabBarIcon.png"];
CustomNavigationBarButton *addButtonView = [[CustomNavigationBarButton alloc] initWithImage:#"AddButton.png" withSelected:#"AddButtonSelected.png"];
[addButtonView addTarget:self action:#selector(gotoCreatePlayers) forControlEvents:UIControlEventTouchUpInside];
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithCustomView:addButtonView];
self.navigationItem.rightBarButtonItem = addButton;
[addButton release];
[addButtonView release];
}
return self;
}
- (void)gotoCreatePlayers {
CreatePlayersViewController *createPlayer = [CreatePlayersViewController new];
[self.navigationController pushViewController:createPlayer animated:YES];
[createPlayer release];
}
When i push my second view, i try to go back into the navigation. But the app crash...
Error appointed:
// -- main.m
int main(int argc, char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int retVal = UIApplicationMain(argc, argv, nil, nil);
[pool release];
return retVal;
}
Thanks guys!

try this:
change:
CreatePlayersViewController *createPlayer = [CreatePlayersViewController new];
to:
CreatePlayersViewController *createPlayer = [CreatePlayersViewController alloc];
also if there are any init methods to call than it should look like this
CreatePlayersViewController *createPlayer = [[CreatePlayersViewController alloc]init];
try somthing like this:
ADD THIS TO THE .h FILE: CreatePlayersViewController *createPlayer
then replace your code above with this:
if (createPlayer ==nil) {
CreatePlayersViewController *nextView = [[CreatePlayersViewController alloc] initWithStyle:UITableViewStylePlain];
self.createPlayer = nextView;
[nextView release];
}
self.meetTheTeam.view.hidden = NO;
[self.navigationController pushViewController:self.meetTheTeam animated:YES];

Related

Creating TabBar programmatically only for one ViewController not in AppDelegate

I want to create a tabBar in my app but only in a detailView not in the AppDelegate. I am searching how to do this in google but everything what I have figured out is in AppDelegate.m
I am trying to do something like this. This shows me a Tab bar with two buttons(without names) but I want to go from one FirstViewController with tabBar, to one of the two items SecondViewController or ThirdViewController with a navigationBar with one backItemButton for get back to the FirstViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self setupTabBar];
}
- (void) setupTabBar {
tabBars = [[UITabBarController alloc] init];
NSMutableArray *localViewControllersArray = [[NSMutableArray alloc] initWithCapacity:4];
YPProfileViewController *profile = [[YPProfileViewController alloc] init];
YPProfileViewController *profile2 = [[YPProfileViewController alloc] init];
[localViewControllersArray addObject:profile];
[localViewControllersArray addObject:profile2];
tabBars.tabBarItem = profile2;
tabBars.viewControllers = localViewControllersArray;
tabBars.view.autoresizingMask==(UIViewAutoresizingFlexibleHeight);
[self.view addSubview:tabBars.view];
}
at least this works for me.
UIViewController *vc1 = [[UIViewController alloc] init];
vc1.title = #"FIRST";
vc1.view.backgroundColor = [UIColor blueColor];
UIViewController *vc2 = [[UIViewController alloc] init];
vc2.title = #"SECOND";
vc2.view.backgroundColor = [UIColor redColor];
UITabBarController *tabBar = [[UITabBarController alloc] init];
tabBar.viewControllers = #[vc1,vc2];
tabBar.selectedIndex = 1;
tabBar.view.frame = CGRectMake(50, 50, 220, 320);
[tabBar willMoveToParentViewController:self];
[self.view addSubview:tabBar.view];
[self addChildViewController:tabBar];
[tabBar didMoveToParentViewController:self];

Error: Creating Tab-Navigation programmatically

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.

How to access to parentViewController after presentModalViewController?

I need to access to parentViewController after presentMoalViewController.
This is my method that I call in the firstViewController to view the secondViewController:
- (void)viewData {
SecondViewController *viewCtrl = [self.storyboard instantiateViewControllerWithIdentifier:#"select_data"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewCtrl];
navigationController.navigationBar.barStyle = UIBarStyleBlack;
UIBarButtonItem *saveButton = [[[UIBarButtonItem alloc] initWithTitle:#"Save" style:UIBarButtonItemStyleDone target:viewCtrl action:#selector(saveData)] autorelease];
viewCtrl.navigationItem.rightBarButtonItem = salvaButton;
UIBarButtonItem *undoButton = [[[UIBarButtonItem alloc] initWithTitle:#"Undo" style:UIBarButtonItemStyleBordered target:viewCtrl action:#selector(backView)] autorelease];
viewCtrl.navigationItem.leftBarButtonItem = annullaButton;
[self presentModalViewController:navigationController animated:YES];
}
When I click on saveButton, I try to access to parentViewController in this way, but it not work:
- (void) saveData {
FirstViewController *parentView = (FirstViewController*)[[self navigationController] presentingViewController];
parentView.dataString = [[NSMutableString alloc] initWithFormat:#"new string"];
[parentView performSelectorInBackground:#selector(myMethod) withObject:nil];
[self dismissModalViewControllerAnimated:YES];
}
It would be much better if you used a delegate/protocol in your second viewController that the first viewController could set itself as. You can find more info here Pass data back to the previous controller or simply doing a search. This design pattern is used virtually everywhere in iOS programming.
The big advantage is that then your second viewController becomes independent of whoever presented it, and can be easily reused. The technical term would be 'decoupling'.
Last time I did this I used notifications:
[[NSNotificationCenter defaultCenter] postNotificationName:#"saveData" object:dataString];
in your parent vc view didload:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(saveDataNow:) name:#"saveData" object:nil];
For navigationController you can declare a property called something like myController, then you have to initiate your navigationController like this:
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewCtrl];
navigationController.navigationBar.barStyle = UIBarStyleBlack;
navigationController.myController = self;
UIBarButtonItem *saveButton = [[[UIBarButtonItem alloc] initWithTitle:#"Save" style:UIBarButtonItemStyleDone target:viewCtrl action:#selector(saveData)] autorelease];
viewCtrl.navigationItem.rightBarButtonItem = salvaButton;
UIBarButtonItem *undoButton = [[[UIBarButtonItem alloc] initWithTitle:#"Undo" style:UIBarButtonItemStyleBordered target:viewCtrl action:#selector(backView)] autorelease];
viewCtrl.navigationItem.leftBarButtonItem = annullaButton;
[self presentModalViewController:navigationController animated:YES];
In your parentViewController Class you declare your Method
- (void) saveData {
FirstViewController *parentView = (FirstViewController*)[[self navigationController] presentingViewController];
parentView.dataString = [[NSMutableString alloc] initWithFormat:#"new string"];
[parentView performSelectorInBackground:#selector(myMethod) withObject:nil];
[self dismissModalViewControllerAnimated:YES];
}
In your navigationController you can then call [myController saveData];
This should work, if you have any questions, feel free to ask!
You can access your parent view controller using following-
- (void) saveData {
NSMutableArray *activeControllerArray = [self.navigationController.viewControllers mutableCopy];
FirstViewController *parentView;
for(int i = 0, i <[activeControllerArray count], i++) {
if([[activeControllerArray objectAtIndex:i] isKindOfClass:[FirstViewController class]) {
parentView= [activeViewController objectAtIndex:i];
break;
}
}
parentView.dataString = [[NSMutableString alloc] initWithFormat:#"new string"];
[parentView performSelectorInBackground:#selector(myMethod) withObject:nil];
[self dismissModalViewControllerAnimated:YES];
}

UITabBar Title Not Showing

I've implemented a UITabBar programmatically exactly the way Apple recommends, and I can't get the title to show up. Here is how I'm implementing it:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UITabBarController *tabBarController = [[UITabBarController alloc] init];
MainViewController *mainViewController = [[MainViewController alloc] init];
UINavigationController *mainNavigationController = [[UINavigationController alloc] initWithRootViewController: mainViewController];
[[mainNavigationController navigationBar] setBarStyle: UIBarStyleBlack];
[tabBarController setViewControllers: [NSArray arrayWithObjects: mainNavigationController, nil]];
[self.window setRootViewController: tabBarController];
[self.window makeKeyAndVisible];
[mainViewController release];
[mainNavigationController release];
[tabBarController release];
return YES;
}
Here is the init method of mainViewController where I add the title:
#implementation MainViewController
- (id) init
{
self = [super initWithNibName: nil bundle: nil];
if (self)
{
UITabBarItem *tabBarItem = [[UITabBarItem alloc] initWithTitle:#"Main" image: nil tag: 1];
[self setTabBarItem: tabBarItem];
[tabBarItem release];
}
return self;
}
I noticed there are a bunch of other questions on this, and some have hacky type solutions, but I'm wondering if Apple is recommending this way, why isn't it working??
This can be done in a variety of ways. The simplest one is to try setting
self.title = #"Main";
This should be reflected in both your navigationBar title and tabBarItem title.
Or , you could just connect them to the interface builder and type it out yourself and connect the outlets properly.

problem with UIPopoverController while navigation

I have UIPopoverController and two ViewController class.
SaveProject and ProjectName is viewController class.
When i am clicking save project. its give me navigation and load another view.
But the UIPopoverController size height is getting increased to the total view size.
Can any one help me out with this..
I am attaching here code:
-(void)createSaveAndCloseView{
saveAndCloseViewController = [[WGSaveAndCloseViewController alloc]init];
[saveAndCloseViewController.view setFrame:CGRectMake(0, 0, 310, 171)];
saveAndCloseViewController.navigationItem.title = #"Save or Discard";
UIBarButtonItem *cancel = [[UIBarButtonItem alloc] initWithTitle:#"Cancel" style:UIBarButtonItemStylePlain target:self action:#selector(cancelAction:)];
saveAndCloseViewController.navigationItem.rightBarButtonItem = cancel;
[cancel release];
UINavigationController *navControl = [[UINavigationController alloc] initWithRootViewController:saveAndCloseViewController];
saveAndClosePopupView = [[UIPopoverController alloc] initWithContentViewController:navControl];
saveAndClosePopupView.delegate = self;
saveAndClosePopupView.popoverContentSize = CGSizeMake(312, 160);
saveAndCloseViewController.view.contentMode = UIViewContentModeScaleAspectFill;
[saveAndClosePopupView presentPopoverFromRect:[saveAndClose bounds] inView:saveAndClose permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
[navControl release];
}
-(void)saveProjectClick:(id)sender{
if (saveProject.tag == tagSave) {
WGNameProjectViewController *nameProjectViewController = [[WGNameProjectViewController alloc] initWithNibName:nil bundle:nil];
[self.navigationController pushViewController:nameProjectViewController animated:YES];
nameProjectViewController.navigationItem.title = #"Name Project";
[nameProjectViewController release];
nameProjectViewController = nil;
}
}
You just need to add something like:
self.preferredContentSize = <view size>
to the viewWillAppear: method in each of your view controllers that are displayed in the popover.