I've got into a very strange problem. I created my own UITabBarController to customize it and it works pretty w开发者_开发问答ell... 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.
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.
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!
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.
精彩评论