Trying to make a custom TabBar. Crash with viewController transitions in iPhone 3GS (but not in iPhone 4)

0

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!

objective-c
ios
crash
transition
viewcontroller
asked on Stack Overflow Jun 8, 2012 by Andrés • edited Jun 8, 2012 by Andrés

1 Answer

2

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

answered on Stack Overflow Jun 8, 2012 by Bo. • edited May 23, 2017 by Community

User contributions licensed under CC BY-SA 3.0