views:

728

answers:

3

Hi everyone,

I've got into a very strange problem. I created my own UITabBarController to customize it and it works pretty well... except for the modal views. When I dismiss the modal view (present/dismiss from the UITabBarController) with an animation, it waits until the animation did finished and goes to the first controller of the tab bar!

Why does the controller change? and how can I fix it?

Thanks

PS: My UITabBarController view is on the main window and has a UITabBar on it. The controllers (which are managed by the tab bar) are on the main window over the tab bar controller view with a shorter height. When I present the modal view, I bring the tab bar controller view to front.

A: 

I have some questions:

1) When you say "created my own UITabBarController" do you mean that you subclassed UITabBarController?

2) How is the call made to present the modal view controller? Is there a button or something that is being tapped that makes a call to present the modal view controller?

You say that the controllers "are on the main window" and that when you present the modal view you "bring the tab bar controller view to front". This confuses me. The view controllers should "belong" to the tab bar controller.

I created a small project and had it work for me so here's what I did:

1) I created a subclass of UITabBarController:

@interface MyTabBarController : UITabBarController
{
}

- (IBAction)presentModalView:(id)sender;
- (void)dismissModalview;

@end


@implementation MyTabBarController

- (IBAction)presentModalView:(id)sender
{
    MyModalViewController* myModalView = [[MyModalViewController alloc] initWithNibName:@"ModalView" bundle:nil];
    [myModalView setTbc:self];
    [self presentModalViewController:myModalView animated:YES];
}

- (void)dismissModalview;
{
    [self dismissModalViewControllerAnimated:YES];
}
@end

2) Then for my modal view controller I created a subclass of UIViewController:

@interface MyModalViewController : UIViewController
{
    MyTabBarController* tbc;
}

@property (retain) MyTabBarController* tbc;

- (IBAction)returnToTabBar:(id)sender;

@end


@implementation MyModalViewController

@synthesize tbc;

- (IBAction)returnToTabBar:(id)sender;
{
    [tbc dismissModalview];
}

@end

3) I dragged a tab bar controller into the MainWindow.xib, set its File's Owner to MyTabBarController, and added view controllers to both tabs (I set the background colors of each to a different color using the inspector). In the second tab's view controller, I added a button and set its target to be the action "presentModalView:" in MyTabBarController.

4) I created a new xib that contains a view called ModalView and set its File's Owner to MyModalViewController. I set the background color of the view to a different color from the two above and added a button to the view. I set the button's target to the action "returnToTabBar:" in MyModalviewController.

Obviously, I had to add the tab bar view to the subview of window in the app delegate. This worked for me and presented a modal view controller when I was on the second tab and when I dismissed it I was returned to the second tab in the tab bar controller.

I hope this helps!

yabada
so... to answer your questions: 1. NO it' s a subclass of UIViewController and 2: YES it's a button on one of the viewWhat I did is put my customUITabBarController on the main window and my managed (by the customUITabBarController) view controller too... On the view of my customUITabBarController, I have the UITabBar. Hope it's clear! I don't know how to explain better
ncohen
+1  A: 

After reading your comment to my first answer, I understand better what you are doing though figuring out what is going wrong is very difficult without seeing the code. I created another project with a custom tab bar controller (subclassed from UIViewController) where one tabbed view has a button that presents a modal view controller. When I dismiss the modal view it goes back to the tab that I was on.

In your question you say that your view controllers managed by the tab bar are on the main window, and when you present the modal view that you bring the tab bar controller view to front. This doesn't make sense to me.

For my example, I made CustomTabBarController a subclass of UIViewController and made instance variables for a tab bar with two tab bar items, and two view controllers. I added the tab bar and both views of the member view controllers as subviews of the CustomTabBarController's view (I set the frames of the view controllers' views so they don't overlap the tab bar). I also set the CustomTabBarController as the delegate of the tab bar. When a tab bar item is selected I send the message bringSubviewToFront: to the CustomTabBarController's view with the appropriate subview as the argument.

One of the member view controllers view has a button that, when tapped, presents the modal view. The view controller could call presentModalViewController: when the button is tapped but, since you said that your tab bar controller is doing that, I have an IBAction method in the view controller (this is the target of the button that presents the modal view) that calls a method in CustomTabBarController that makes the call to presentModalViewController:. The view controller has an ivar for the CustomTabBarController (since the view controller belongs to CustomTabBarController this was easy to set).

The modal view controller class also has an ivar for the CustomTabBarController (I set this just before calling presentModalViewController:) and I have a button in the modal view that dismisses the modal view. That button is hooked up to an IBAction in the modal view controller class which then calls a method in the CustomTabBarController.

Everything works as expected when I do it this way. I'm sure you have you reasons for creating a custom tab bar controller but I question whether it is really necessary. I hope this helps.

yabada
Hey, first thank you so much for taking the time to answer...I really appreciate! I wanted a customized tabBar because I want to manage the tab bar in a particular way. I want it to have (sometimes) nothing selected on it because more than 5 controllers are managed by the tabbar. I also want to change the height of the tabbar... anyway, I really need to have that! I also need to have sometimes the navigation bar and sometimes not so in order to have that, I had to put my controllers on the window and not on the customized tabbar controller (view). I could send it to you but can't write here...
ncohen
I don't get having nothing selected on the tab bar. If the tab bar is showing, a tab should be selected shouldn't it? Otherwise, what view is showing and how does that view relate to the tab bar? When you say you sometimes have the navigation bar and sometimes not, what does that mean specifically? Does that mean on some tab views you'll have a navigation bar and some you won't? Are you really sure that your design is correct. It sounds like your design is awkward and it could/should be done a different way. Not sure, of course, but that's the way it appears.
yabada
I know...it seems awkward but it's not!I want to optimize my view so when something is not needed I hide it. 1)I have a table view (in one of my tabBar controller) when I tap a cell I get a new controller with the navigation bar... does it make sense to hide the navigation bar in my table view? for me it does! 2)I have a main menu with icons (like on the iPhone OS). When I tap one of these icons, I get into the controller with the tab bar but sometimes the menu is not very important so it s not present on the tab bar (with the tab bar,the user has always access to the important menus)mk sense?
ncohen
Don't get me wrong, I'm not talking about the GUI design or the functionality of your app but the software design/architecture. In terms of your original question and the complexity of your app that's probably where the answer lies.
yabada
you're right... but everything is working except for the modal views... so I still have hope!
ncohen
Good luck...I hope you figure it out! Sorry I couldn't help more.
yabada
A: 

I suspect you're doing a lot of (too much?) initialisation work in viewDidLoad and one of those things is selecting the first tab?

Maybe you can share with us the sequence of init/load in your custom Tab bar controller class?

Your Tab bar controller view may be unloading while the modal view is displayed, and reloaded (calling viewDidLoad) when the modal is dismissed.

My advice is to set some debugger breakpoints at tab-switching and view-loading methods and examine the call stack to ensure the lifecycle of your Tab bar controller matches your understanding.

ohhorob