First, I'm new to iOS and Objective-C programming (I started a month ago).
I'm trying to do a custom tabBar, and it works great in my iPhone 4 with iOS 5.1.1, but it doesn't with 3GS with iOS 4.2.1. I'd update it to see if it's something related to the iOS version instead of the phone model, but I prefer to have it in iOS 4 to do testing.
First, I would be very pleased if anyone helps me to figure out what's causing this crash and how to avoid it. Well, as it is shown in the call stack, it seems that my viewController does not respond to the transitionFromViewController:toViewController:duration:options:animations:completion:
, but it is working in iOS 5... Could it be it's a new function not present in iOS 4? And if this is what is just happening, how can I make a transition from a viewController to another without this selector?
Second, I'd like to know if I'm doing it the right way: As I mentioned before, what I want is my own custom TabBar. What I did is to make a viewController which has 5 buttons and almost the whole screen is a view with an outlet to load in it the corresponding viewController depending on which button is pressed. For example:
- Header:
// CustomTabBarViewController.h
#import <UIKit/UIKit.h>
#import "Tab1ViewController.h"
@interface TabBarCustomViewController : UIViewController
// View Controllers
@property (retain, nonatomic) Tab1ViewController *myTab1ViewController;
@property (retain, nonatomic) Tab2ViewController *myTab2ViewController;
// Reference of the current shown viewController, for the transitions
@property (retain, nonatomic) UIViewController *currentViewController;
// Outlet to switch the viewController inside the view mainView;
@property (retain, nonatomic) IBOutlet UIView *mainView;
- .m file
#import "TabBarCustomViewController.h"
@interface TabBarCustomViewController ()
@end
@implementation TabBarCustomViewController
@synthesize myTab1ViewController, myTab2ViewController;
@synthesize currentViewController;
@synthesize mainView;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
//Instantiation of the viewControllers
self.myTab1ViewController = [[Tab1ViewController alloc]initWithNibName:@"Tab1ViewController" bundle:nil];
self.myTab2ViewController = [[Tab2ViewController alloc]initWithNibName:@"Tab2ViewController" bundle:nil];
// Adding those viewControllers to the root viewController
[self addChildViewController:self.myTab1ViewController];
[self addChildViewController:self.myTab2ViewController];
//the entry view
[mainView addSubview:self.myTab1ViewController.view];
currentViewController = self.myTab1ViewController;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
// My methods
- (IBAction)tab1Pressed
{
NSLog(@"tab1Pressed");
[self transitionFromViewController:currentViewController toViewController:self.myTab1ViewController duration:0.2 options:UIViewAnimationOptionTransitionCrossDissolve animations:nil completion:nil];
// Updating the reference of which viewController is currently being displayed
currentViewController = myTab1ViewController;
}
- (IBAction)tab2Pressed
{
NSLog(@"tab2Pressed");
[self transitionFromViewController:currentViewController toViewController:self.myTab2ViewController duration:0.2 options:UIViewAnimationOptionTransitionCrossDissolve animations:nil completion:nil];
// Updating the reference of which viewController is currently being displayed
currentViewController = myTab2ViewController;
}
@end
- This is what is thrown in the console when the crash mentioned in the first point occurs:
2012-06-08 08:25:55.991 myTabBar[4597:307] tab2Pressed
2012-06-08 08:25:56.003 myTabBar[4597:307] -[TabBarCustomViewController transitionFromViewController:toViewController:duration:options:animations:completion:]: unrecognized selector sent to instance 0x143cc0
2012-06-08 08:25:56.028 myTabBar[4597:307] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[TabBarCustomViewController transitionFromViewController:toViewController:duration:options:animations:completion:]: unrecognized selector sent to instance 0x143cc0'
*** Call stack at first throw:
(
0 CoreFoundation 0x314d0987 __exceptionPreprocess + 114
1 libobjc.A.dylib 0x319a149d objc_exception_throw + 24
2 CoreFoundation 0x314d2133 -[NSObject(NSObject) doesNotRecognizeSelector:] + 102
3 CoreFoundation 0x31479aa9 ___forwarding___ + 508
4 CoreFoundation 0x31479860 _CF_forwarding_prep_0 + 48
5 myTabBar 0x00003707 -[TabBarCustomViewController tab2Pressed] + 126
6 CoreFoundation 0x31477fed -[NSObject(NSObject) performSelector:withObject:withObject:] + 24
7 UIKit 0x338c14ad -[UIApplication sendAction:to:from:forEvent:] + 84
8 UIKit 0x338c144d -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 32
9 UIKit 0x338c141f -[UIControl sendAction:to:forEvent:] + 38
10 UIKit 0x338c1171 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 356
11 UIKit 0x338c19cf -[UIControl touchesEnded:withEvent:] + 342
12 UIKit 0x338b7355 -[UIWindow _sendTouchesForEvent:] + 368
13 UIKit 0x338b6ccf -[UIWindow sendEvent:] + 262
14 UIKit 0x338a1fc7 -[UIApplication sendEvent:] + 298
15 UIKit 0x338a1907 _UIApplicationHandleEvent + 5090
16 GraphicsServices 0x35d66f03 PurpleEventCallback + 666
17 CoreFoundation 0x314656ff __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 26
18 CoreFoundation 0x314656c3 __CFRunLoopDoSource1 + 166
19 CoreFoundation 0x31457f7d __CFRunLoopRun + 520
20 CoreFoundation 0x31457c87 CFRunLoopRunSpecific + 230
21 CoreFoundation 0x31457b8f CFRunLoopRunInMode + 58
22 GraphicsServices 0x35d664ab GSEventRunModal + 114
23 GraphicsServices 0x35d66557 GSEventRun + 62
24 UIKit 0x338d5329 -[UIApplication _run] + 412
25 UIKit 0x338d2e93 UIApplicationMain + 670
26 myTabBar 0x000027cb main + 102
27 myTabBar 0x00002760 start + 40
)
terminate called after throwing an instance of 'NSException'
(lldb)
I know I can use [mainView addSubview:myTab1ViewController.view];
instead of [self transitionFromViewController:currentViewController toViewController:self.myTab2ViewController duration:0.2 options:UIViewAnimationOptionTransitionCrossDissolve animations:nil completion:nil];
But this way I can't do transition animations, besides I'm not sure if it's the proper way of doing what I want to do.
Thank you in advance!
According to official docs: http://developer.apple.com/library/ios/documentation/uikit/reference/UIViewController_Class/Reference/Reference.html#//apple_ref/occ/instm/UIViewController/transitionFromViewController:toViewController:duration:options:animations:completion:
transitionFromViewController:toViewController:duration:options:animations:completion is available:
Availability
Available in iOS 5.0 and later.
So you can expect unrecognized selector sent to instance
in all versions prior to iOS 5.0
For custom TabBars you might want to checkout following posts:
http://mobiledevelopertips.com/open-source/ios-open-source-custom-tabbar-controller-bctabbarcontroller.html
https://stackoverflow.com/a/4912328/200272
User contributions licensed under CC BY-SA 3.0