I tried to include a custom button programmatically inside a UIView which is a subview of UITabBarController.
The button is displays fine but when I click it, it crashes without an error message. Its strange that sometimes it does inconsistently:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFString playButton]: unrecognized selector sent to instance 0x632cd10'
I even tried removing any code in my play button method, i tried changing the name playButton to playAction, I also tried add the button directly to "self" not to aboutView but the result is still the same.
My guess is it got something to do with the tabBar having a UIView as a subview with a button on it. I don't know.
Here's a code snippet of how i built the tabBar in my appDelegate method
// About Tab
aboutViewC = [[[AboutViewController alloc] init] autorelease];
aboutNavC = [[[UIViewController alloc] init] autorelease];
aboutNavC.title = #"About";
aboutNavC.view = aboutViewC.view;
// Lessons Tab
lessonsViewC = [[[LevelViewController alloc] init] autorelease];
lessonsViewC.title = #"Levels";
lessonsNavC = [[[UINavigationController alloc] initWithRootViewController:lessonsViewC] autorelease];
lessonsNavC.title = #"Lessons";
lessonsNavC.viewControllers = [NSArray arrayWithObjects:lessonsViewC, nil];
tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [NSArray arrayWithObjects:aboutNavC, lessonsNavC, nil];
and heres the code for implementing the AboutViewController class
AboutViewController.h
#import
#interface AboutViewController : UIViewController {
UIButton *playSoundButton;
UIView *aboutView;
}
- (void)playButton;
#end
AboutViewController.m
#import "AboutViewController.h"
#implementation AboutViewController
- (void)dealloc {
[playSoundButton release];
[aboutView release];
[super dealloc];
}
- (void)viewDidLoad {
aboutView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
[playSoundButton = [UIButton buttonWithType:UIButtonTypeCustom] retain];
image = [UIImage imageNamed:#"bt_play.png"];
[playSoundButton setImage:image forState:UIControlStateNormal];
[playSoundButton addTarget:self action:#selector(playButton) forControlEvents:UIControlEventTouchUpInside];
playSoundButton.frame = CGRectMake(0, 350, 40, 40);
[aboutView addSubview:playSoundButton];
stopSoundButton.hidden = YES;
playSoundButton.hidden = NO;
[self.view addSubview:aboutView];
[super viewDidLoad];
}
- (void)playButton
{
NSLog(#"playAction method");
}
#end
Thanks in advance!
[playSoundButton = [UIButton buttonWithType:UIButtonTypeCustom] retain]; should read playSoundButton = [[UIButton buttonWithType:UIButtonTypeCustom] retain];
(i.e. move the first [ further right to UIButton)
Thanks tob for the feedback, i actually know how to implement retain statement, it was a typo i didn't notice. surprisingly, that is not the problem and the code run's fine now leaving the typo unchanged.
The real problem was in my appDelegate method.
Instead of
// About Tab
aboutViewC = [[[AboutViewController alloc] init] autorelease];
aboutNavC = [[[UIViewController alloc] init] autorelease];
aboutNavC.title = #"About";
aboutNavC.view = aboutViewC.view;
// Lessons Tab
lessonsViewC = [[[LevelViewController alloc] init] autorelease];
lessonsViewC.title = #"Levels";
lessonsNavC = [[[UINavigationController alloc] initWithRootViewController:lessonsViewC] autorelease];
lessonsNavC.title = #"Lessons";
lessonsNavC.viewControllers = [NSArray arrayWithObjects:lessonsViewC, nil];
tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [NSArray arrayWithObjects:aboutNavC, lessonsNavC, nil];
should be
// About Tab
aboutViewC = [[[AboutViewController alloc] init] autorelease];
aboutViewC.title = #"About";
// Lessons Tab
lessonsViewC = [[[LevelViewController alloc] init] autorelease];
lessonsViewC.title = #"Levels";
lessonsNavC = [[[UINavigationController alloc] initWithRootViewController:lessonsViewC] autorelease];
lessonsNavC.title = #"Lessons";
lessonsNavC.viewControllers = [NSArray arrayWithObjects:lessonsViewC, nil];
tabBarController = [[UITabBarController alloc] init];
tabBarController.viewControllers = [NSArray arrayWithObjects:aboutViewC, lessonsNavC, nil];
Related
Please check below code . I need to implement tabbar and facebook slide menu together.
tabBarController.delegate = self;
self.leftController = [[LeftViewController alloc] initWithNibName:#"LeftViewController" bundle:nil];
RightViewController* rightController = [[RightViewController alloc] initWithNibName:#"RightViewController" bundle:nil];
// ViewController *centerController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
FirstViewController *centerController = [[FirstViewController alloc] initWithNibName:#"FirstView" bundle:nil];
self.centerController = [[UINavigationController alloc] initWithRootViewController:centerController];
IIViewDeckController* deckController = [[IIViewDeckController alloc] initWithCenterViewController:self.centerController
leftViewController:self.leftController
rightViewController:rightController];
deckController.rightSize = 100;
self.window.rootViewController = deckController;
// Add the tab bar controller's view to the window and display.
[self.window addSubview:tabBarController.view];
Since it looks like you're using the IIViewDeckController, look at its automaticallyUpdateTabBarItems property.
I've created a new "Tab Bar project" with the new Xcode 4.2. The "new" way to work with UITabBar is different: Xcode doesn't create a xib file (with the UITabBarController), but it does everything via code. Ok, let's do it.
So my code in didFinishLaunchingWithOptions is this:
UIViewController *viewController1, *viewController2, *viewController3;
UINavigationController *nav1, *nav2, *nav3;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
viewController1 = [[gemboy_iphone alloc] initWithNibName:#"vc1" bundle:nil];
viewController2 = [[concerti_iphone alloc] initWithNibName:#"vc2" bundle:nil];
viewController3 = [[discografia_iphone alloc] initWithNibName:#"vc3" bundle:nil];
nav1 = [[UINavigationController alloc] initWithRootViewController:viewController1];
nav2 = [[UINavigationController alloc] initWithRootViewController:viewController2];
nav3 = [[UINavigationController alloc] initWithRootViewController:viewController3];
}
else {
//same thing for the iPad version
}
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:nav1, nav2, nav3, nil];
self.window.rootViewController = self.tabBarController;
[self.window addSubview:self.splash.view];
[self.window makeKeyAndVisible];
return YES;
And it works.
My three .m files vc1.m, vc2.m and vc3.m (and also my iPad UIViewControllers) has this method
- (BOOL)shouldAutorotate {
return YES;
}
The problem is that when I rotate the iPhone, it's not rotating.
Any one please tell me where i done mistake and any thing wrong?
You should subclass the uitabbarcontroller and implemetn
- (BOOL)shouldAutorotate
{
return YES;
}
- (NSUInteger)supportedInterfaceOrientations
{
return UIInterfaceOrientationMaskAll;
}
I need to create an app with a Split View but I need to add a tab bar in the Master side of the split, I've read some stuff in this forum but I just can't get it right.
I understand that when you have a split view you actually handle two view controllers the master and the detail so, to my understanding, if I need a tab bar in the master side I have to call the master from the appDelegate and inside this master I can set it up as a Tab Bar controller but either I have a complete misconception or I'm just implementing it wrong.
Here's what I'm doing in the appDelegate, as you can see I'm loading another VC than the master VC that comes with the template, my first question is if I have to load a VC or just an NSObject with the tab bar protocol?:
WTDInitialViewController *initialViewController = [[WTDInitialViewController alloc] initWithNibName:#"WTDInitialViewController" bundle:nil];
UINavigationController *initialNavigationController = [[UINavigationController alloc] initWithRootViewController:initialViewController];
WTDDetailViewController *detailViewController = [[WTDDetailViewController alloc] initWithNibName:#"WTDDetailViewController_iPad" bundle:nil];
UINavigationController *detailNavigationController = [[UINavigationController alloc] initWithRootViewController:detailViewController];
self.splitViewController = [[UISplitViewController alloc] init];
self.splitViewController.delegate = detailViewController;
self.splitViewController.viewControllers = [NSArray arrayWithObjects:initialNavigationController, detailNavigationController, nil];
self.window.rootViewController = self.splitViewController;
Now, this is what I do in the so called VC
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
NSMutableArray *vcArray = [[NSMutableArray alloc] initWithCapacity:1];
_tabBarController = [[UITabBarController alloc] init];
WTDMasterViewController *masterViewController = [[WTDMasterViewController alloc] initWithNibName:#"WTDMasterViewController_iPad" bundle:nil];
_navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
_navigationController.navigationBar.barStyle = UIBarStyleBlack;
[vcArray addObject:_navigationController];
_tabBarController.viewControllers = vcArray;
_tabBarController.moreNavigationController.navigationBar.barStyle = UIBarStyleBlack;
self.tabBarController.selectedIndex = 0;
[_window addSubview:_tabBarController.view];
[_window makeKeyAndVisible];
}
return self;
It may be a stupid question but I hit a dead end so, any help will be much appreciated
First, I'm assuming you are creating SplitView for ipad. It's initial comes with MasterViewController and DetailViewController. And the MasterViewController is UITableview base, now you want to implement Tabbar base instead, then just call do this in ViewWillAppear of MasterViewController.
UIViewController *viewController1 = [[[YourTabView1 alloc] initWithNibName:#"YourTabView1" bundle:nil]autorelease];
//If you want the view support Navigation then do this
UINavigationController *tab1 = [[[UINavigationController alloc] initWithRootViewController:viewController1]autorelease];
UIViewController *viewController2 = [[[YourTabView2 alloc] initWithNibName:#"YourTabView2" bundle:nil]autorelease];
UINavigationController *tab2 = [[[UINavigationController alloc] initWithRootViewController:viewController2]autorelease];
UITabBarController *tabbarController = [[UITabBarController alloc] init];
tabbarController.viewControllers = [NSArray arrayWithObjects:tab1,tab2,nil];
[self presentModalViewController:tabbarController animated:YES];
I think this should work(but I didnt test the code).
TabBar will be about 2 question. I am using a combination of a TabBar and NavigationController. As the following link.
http://developer.apple.com/library/ios/#featuredarticles/ViewControllerPGforiPhoneOS/CombiningViewControllers/CombiningViewControllers.html
Question 1:
I would like to appear before a TabBar to another ViewController. Several checks are here to do. (For example, Facebook login) If the prerequisites are met, tabbar will be visible. How do I do?
Question 2:
TabBar screen icon that appears in the middle of the first TabBar want it to be. The following code sequence also affects the order of TabBarItem.
self.tabBarController.viewControllers = [NSArray arrayWithObjects: viewController1, viewController2, nil];
Thank you.
Okan Sahin
For those who have the same problem:
I'm using Xcode 4.2. I have created Tabbed App.
Answer 1:
For loading screen,
I created a new ViewController.
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIViewController *viewControllerLoading = [[LoadingViewController alloc] initWithNibName:#"LoadingViewController" bundle:nil];
self.window.rootViewController = viewControllerLoading;
[self.window makeKeyAndVisible];
return YES;
}
LoadingViewController.h
#interface LoadingViewController : UIViewController <UITabBarControllerDelegate>
#property (strong, nonatomic) UITabBarController *tabBarController;
#end
LoadingViewController.m
UIViewController *viewControllerFriends = [[FriendsViewController alloc] initWithNibName:#"FriendsViewController" bundle:nil];
UINavigationController* navController1 = [[UINavigationController alloc]
initWithRootViewController:viewControllerFriends];
UIViewController *viewConrollerMessages = [[MessagesViewController alloc] initWithNibName:#"MessagesViewController" bundle:nil];
UINavigationController* navController2 = [[UINavigationController alloc]
initWithRootViewController:viewConrollerMessages];
UIViewController *viewControllerWorld = [[WorldViewController alloc] initWithNibName:#"WorldViewController" bundle:nil];
UINavigationController* navController3 = [[UINavigationController alloc]
initWithRootViewController:viewControllerWorld];
UIViewController *viewControllerCheckIn = [[CheckInViewController alloc] initWithNibName:#"CheckinViewController" bundle:nil];
UINavigationController* navController4 = [[UINavigationController alloc]
initWithRootViewController:viewControllerCheckIn];
UIViewController *viewControllerProfile = [[ProfileViewController alloc] initWithNibName:#"ProfileViewController" bundle:nil];
UINavigationController* navController5 = [[UINavigationController alloc]
initWithRootViewController:viewControllerProfile];
self.tabBarController = [[UITabBarController alloc] init];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:navController1, navController2, navController3, navController4, navController5, nil];
[self.view addSubview:self.tabBarController.view];
Answer 2:
self.tabBarController.selectedIndex = 2;
Best regards
Okan Sahin
I have added tabbarcontroller, setViewControllers used for providing array of uiviewcontroller. viewDidLoad is called for this viewContollers but not viewDidAppear neither viewWillAppear.
the code I have written
- (void)loadView {
printf("*********\n loadView \n********* ");
UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];
contentView.backgroundColor = [UIColor whiteColor];
self.view = contentView;
[contentView release];
UITabBarController *tabbar = [[UITabBarController alloc] init];
tabbar.view.frame = CGRectMake(0, 0, 320, 460);
piechartViewController *pr=[[piechartViewController alloc]init];
pr.tagInAction=1;
pr.title=#"Type";
pr.tabBarItem.image=[UIImage imageNamed:#"trend.png"];
pr.sDate=sDate;
pr.nDate=nDate;
piechartViewController *pr1=[[piechartViewController alloc]init];
pr1.title=#"category";
pr1.tagInAction=4;
pr1.sDate=sDate;
pr1.nDate=nDate;
piechartViewController *pr2=[[piechartViewController alloc]init];
pr2.title=#"paidWith";
pr2.tagInAction=3;
pr2.sDate=sDate;
pr2.nDate=nDate;
[tabbar setViewControllers:[NSArray arrayWithObjects:pr,pr1,pr2,nil]];
[self.view addSubview:tabbar.view ];
[pr release];
[pr1 release];
[pr2 release];
}
Hey, are you sure you want to work with loadView and not with viewDidLoad instead?
And might you paste the code when you call this view controller?
Btw, "self.view = contentView"? Probably [self.view addSubview:contentView] sounds better, don't you think?