开发者

Why are my TabBar buttons disabled the first time I load my view controller?

I have an iPhone app where I switch between 2 tab bars. The problem is that in the view where I swap the tab bars, my tab bar buttons are disabled only the first time the view loads (when loadView and viewDidLoad are called). In other words, if I navigate to that view the tab bar buttons are disabled. If I navigate to something from that view and then pop back, the buttons are enabled. The difference in the view lifecycle calls are:

Working - loadView viewDidLoad viewWillAppear viewDidAppear

Not Working - viewWillAppear viewDidAppear

Right now the swap is in viewDidAppear. If I put the swap in viewWillAppear the buttons work fine but the view controller jumps down because tab bar swapping animation is done during the view transition animation.

My first guess was that some view was sitting on top of the tab bar. I don't think that is true. I printed out the view hierarchies in both scenarios and there is only one small difference.

Here is the view hierarchy for the working scenario:

<UIWindow: 0x5a4c7c0; frame = (0 0; 320 480); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x5a4ca30>>
   | <UILayoutContainerView: 0x5a591b0; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x5a59230>>
   |    | <UITransitionView: 0x5a59c00; frame = (0 0; 320 480); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x5a59ca0>>
   |    |    | <UIViewControllerWrapperView: 0x5a6e960; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x5a6e9e0>>
   |    |    |    | <UILayoutContainerView: 0x5a5bb70; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x5a5bbc0>>
   |    |    |    |    | <UINavigationTransitionView: 0x5a5c290; frame = (0 0; 320 480); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x5a19400>>
   |    |    |    |    |    | <UIViewControllerWrapperView: 0xaf01810; frame = (0 20; 320 460); layer = <CALayer: 0xaf01840>>
   |    |    |    |    |    |    | <UIView: 0x5abcba0; frame = (0 0; 320 460); layer = <CALayer: 0x5a8ff50>>
   |    |    |    |    |    |    |    | <CaptureAuxMenu: 0x5ac6850; frame = (0 480; 320 49); layer = <CALayer: 0x5ac68e0>>
   |    |    |    |    |    |    |    |    | <UIImageView: 0x5ac6a50; frame = (0 0; 320 49); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5ac6a80>>
   |    |    |    |    |    |    |    |    | <UIButton: 0x5ac67c0; frame = (18 7; 80 31); opaque = NO; layer = <CALayer: 0x5ac6b80>>
   |    |    |    |    |    |    |    |    |    | <UIImageView: 0x5acf910; frame = (0 0; 80 31); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5acf940>>
   |    |    |    |    |    |    |    |    | <UIButton: 0x5ac7ed0; frame = (116 7; 80 31); opaque = NO; layer = <CALayer: 0x5ac7b50>>
   |    |    |    |    |    |    |    |    |    | <UIImageView: 0x5acf890; frame = (0 0; 80 31); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5acf8c0>>
   |    |    |    |    |    |    |    |    | <UIButton: 0x5ac91f0; frame = (285 10; 25 25); opaque = NO; layer = <CALayer: 0x5ac8e70>>
   |    |    |    |    |    |    |    |    |    | <UIImageView: 0x5acf810; frame = (0 0; 25 25); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5acf840>>

   |    | <UITabBar: 0x5a59560; frame = (0 431; 320 480); hidden = YES; autoresize = W+TM; layer = <CALayer: 0x5a59600>>
   |    |    | <UITabBarButton: 0x5a638f0; frame = (2 1; 60 479); opaque = NO; layer = <CALayer: 0x5a660a0>>
   |    |    |    | <UITabBarSelectionIndicatorView: 0x5a6e250; frame = (0 2; 60 475); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a6e280>>
   |    |    |    | <UITabBarSwappableImageView: 0x5a662a0; frame = (6 218; 48 32); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a66360>>
   |    |    |    | <UITabBarButtonLabel: 0x5a63ba0; frame = (16 465; 28 13); text = 'string'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a63990>>
   |    |    | <UITabBarButton: 0x5a660d0; frame = (66 1; 60 479); opaque = NO; layer = <CALayer: 0x5a674a0>>
   |    |    |    | <UITabBarSwappableImageView: 0x5a663c0; frame = (6 218; 48 32); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a66410>>
   |    |    |    | <UITabBarButtonLabel: 0x5a66cc0; frame = (16 465; 28 13); text = 'string'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a665e0>>
   |    |    | <UITabBarButton: 0x5a65990; frame = (130 1; 60 479); opaque = NO; layer = <CALayer: 0x5a68140>>
   |    |    |    | <UITabBarSwappableImageView: 0x5a689c0; frame = (6 218; 48 32); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a68170>>
   |    |    |    | <UITabBarButtonLabel: 0x5a696b0; frame = (16 465; 28 13); text = 'string'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a68ba0>>
   |    |    | <UITabBarButton: 0x5a68420; frame = (194 1; 60 479); opaque = NO; layer = <CALayer: 0x5a697d0>>
   |    |    |    | <UITabBarSwappableImageView: 0x5a6abf0; frame = (6 218; 48 32); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a6ac40>>
   |    |    |    | <UITabBarButtonLabel: 0x5a6af20; frame = (8 465; 44 13); text = 'FRIENDS'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a678c0>>
   |    |    | <UITabBarButton: 0x5a6a5a0; frame = (258 1; 60 479); opaque = NO; layer = <CALayer: 0x5a6b230>>
   |    |    |    | <UITabBarSwappableImageView: 0x5a6b9b0; frame = (6 218; 48 32); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a6b260>>
   |    |    |    | <UITabBarButtonLabel: 0x5a677c0; frame = (8 465; 44 13); text = 'PROFILE'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a6b3d0>>
   |    | <UIImageView: 0x5a6b850; frame = (0 480; 320 49); opaque = NO; tag = 89364833; layer = <CALayer: 0x5a6d200>>
   |    |    | <UIButton: 0x5a6d580; frame = (0 0; 64 49); opaque = NO; layer = <CALayer: 0x5a6d660>>
   |    |    |    | <UIImageView: 0x5c35b20; frame = (0 0; 63 49); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5c35b50>>
   |    |    | <UIButton: 0x5a63480; frame = (64 0; 64 49); opaque = NO; tag = 1; layer = <CALayer: 0x5a66170>>
   |    |    |    | <UIImageView: 0x5c35aa0; frame = (0 0; 64 49); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5c35ad0>>
   |    |    | <UIButton: 0x5a6da30; frame = (128 0; 64 49); opaque = NO; tag = 2; layer = <CALayer: 0x5a6dac0>>
   |    |    |    | <UIImageView: 0x5c35a20; frame = (0 0; 64 49); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5c35a50>>
   |    |    | <UIButton: 0x5a6dc60; frame = (192 0; 64 49); opaque = NO; tag = 3; layer = <CALayer: 0x5a6dcf0>>
   |    |    |    | <UIImageView: 0x5c359a0; frame = (0 0; 64 49); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5c359d0>>
   |    |    | <UIButton: 0x5a6de90; frame = (256 0; 64 49); opaque = NO; tag = 4; layer = <CALayer: 0x5a6df20>>
   |    |    |    | <UIImageView: 0x5c358c0; frame = (0 0; 64 49); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5c35970>>

Here is the view hierarchy for the failing scenario:

<UIWindow: 0x5a4c7c0; frame = (0 0; 320 480); opaque = NO; autoresize = RM+BM; layer = <CALayer: 0x5a4ca30>>
   | <UILayoutContainerView: 0x5a591b0; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x5a59230>>
   |    | <UITransitionView: 0x5a59c00; frame = (0 0; 320 480); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x5a59ca0>>
   |    |    | <UIViewControllerWrapperView: 0x5a6e960; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x5a6e9e0>>
   |    |    |    | <UILayoutContainerView: 0x5a5bb70; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x5a5bbc0>>
   |    |    |    |    | <UINavigationTransitionView: 0x5a5c290; frame = (0 0; 320 480); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x5a19400>>
   |    |    |    |    |    | <UIViewControllerWrapperView: 0x5ae49f0; frame = (0 20; 320 411); layer = <CALayer: 0x5ae4870>>
   |    |    |    |    |    |    | <UIView: 0x5abcba0; frame = (0 0; 320 411); layer = <CALayer: 0x5a8ff50>>
   |    |    |    |    |    |    |    | <CaptureAuxMenu: 0x5ac6850; frame = (0 480; 320 49); layer = <CALayer: 0x5ac68e0>>
   |    |    |    |    |    |    |    |    | <UIImageView: 0x5ac6a50; frame = (0 0; 320 49); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5ac6a80>>
   |    |    |    |    |    |    |    |    | <UIButton: 0x5ac67c0; frame = (18 7; 80 31); opaque = NO; layer = <CALayer: 0x5ac6b80>>
   |    |    |    |    |    |    |    |    |    | <UIImageView: 0x5acf910; frame = (0 0; 80 31); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5acf940>>
   |    |    |    |    |    |    |    |    | <UIButton: 0x5ac7ed0; frame = (116 7; 80 31); opaque = NO; layer = <CALayer: 0x5ac7b50>>
   |    |    |    |    |    |    |    |    |    | <UIImageView: 0x5acf890; frame = (0 0; 80 31); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5acf8c0>>
   |    |    |    |    |    |    |    |    | <UIButton: 0x5ac91f0; frame = (285 10; 25 25); opaque = NO; layer = <CALayer: 0x5ac8e70>>
   |    |    |    |    |    |    |    |    |    | <UIImageView: 0x5acf810; frame = (0 0; 25 25); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5acf840>>

   |    | <UITabBar: 0x5a59560; frame = (0 431; 320 480); hidden = YES; aut开发者_高级运维oresize = W+TM; layer = <CALayer: 0x5a59600>>
   |    |    | <UITabBarButton: 0x5a638f0; frame = (2 1; 60 479); opaque = NO; layer = <CALayer: 0x5a660a0>>
   |    |    |    | <UITabBarSelectionIndicatorView: 0x5a6e250; frame = (0 2; 60 475); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a6e280>>
   |    |    |    | <UITabBarSwappableImageView: 0x5a662a0; frame = (6 218; 48 32); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a66360>>
   |    |    |    | <UITabBarButtonLabel: 0x5a63ba0; frame = (16 465; 28 13); text = 'string'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a63990>>
   |    |    | <UITabBarButton: 0x5a660d0; frame = (66 1; 60 479); opaque = NO; layer = <CALayer: 0x5a674a0>>
   |    |    |    | <UITabBarSwappableImageView: 0x5a663c0; frame = (6 218; 48 32); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a66410>>
   |    |    |    | <UITabBarButtonLabel: 0x5a66cc0; frame = (16 465; 28 13); text = 'string'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a665e0>>
   |    |    | <UITabBarButton: 0x5a65990; frame = (130 1; 60 479); opaque = NO; layer = <CALayer: 0x5a68140>>
   |    |    |    | <UITabBarSwappableImageView: 0x5a689c0; frame = (6 218; 48 32); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a68170>>
   |    |    |    | <UITabBarButtonLabel: 0x5a696b0; frame = (16 465; 28 13); text = 'string'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a68ba0>>
   |    |    | <UITabBarButton: 0x5a68420; frame = (194 1; 60 479); opaque = NO; layer = <CALayer: 0x5a697d0>>
   |    |    |    | <UITabBarSwappableImageView: 0x5a6abf0; frame = (6 218; 48 32); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a6ac40>>
   |    |    |    | <UITabBarButtonLabel: 0x5a6af20; frame = (8 465; 44 13); text = 'FRIENDS'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a678c0>>
   |    |    | <UITabBarButton: 0x5a6a5a0; frame = (258 1; 60 479); opaque = NO; layer = <CALayer: 0x5a6b230>>
   |    |    |    | <UITabBarSwappableImageView: 0x5a6b9b0; frame = (6 218; 48 32); opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a6b260>>
   |    |    |    | <UITabBarButtonLabel: 0x5a677c0; frame = (8 465; 44 13); text = 'PROFILE'; clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5a6b3d0>>
   |    | <UIImageView: 0x5a6b850; frame = (0 480; 320 49); opaque = NO; tag = 89364833; layer = <CALayer: 0x5a6d200>>
   |    |    | <UIButton: 0x5a6d580; frame = (0 0; 64 49); opaque = NO; layer = <CALayer: 0x5a6d660>>
   |    |    |    | <UIImageView: 0x5c35b20; frame = (0 0; 63 49); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5c35b50>>
   |    |    | <UIButton: 0x5a63480; frame = (64 0; 64 49); opaque = NO; tag = 1; layer = <CALayer: 0x5a66170>>
   |    |    |    | <UIImageView: 0x5c35aa0; frame = (0 0; 64 49); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5c35ad0>>
   |    |    | <UIButton: 0x5a6da30; frame = (128 0; 64 49); opaque = NO; tag = 2; layer = <CALayer: 0x5a6dac0>>
   |    |    |    | <UIImageView: 0x5c35a20; frame = (0 0; 64 49); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5c35a50>>
   |    |    | <UIButton: 0x5a6dc60; frame = (192 0; 64 49); opaque = NO; tag = 3; layer = <CALayer: 0x5a6dcf0>>
   |    |    |    | <UIImageView: 0x5c359a0; frame = (0 0; 64 49); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5c359d0>>
   |    |    | <UIButton: 0x5a6de90; frame = (256 0; 64 49); opaque = NO; tag = 4; layer = <CALayer: 0x5a6df20>>
   |    |    |    | <UIImageView: 0x5c358c0; frame = (0 0; 64 49); clipsToBounds = YES; opaque = NO; userInteractionEnabled = NO; layer = <CALayer: 0x5c35970>>

The only noticeable difference I can see is on line #7 and line #8 in both scenarios. You will see that the UIViewControllerWrapperView and child UIView have different frames but I'm not quite sure why that would be an issue because I am not sure which UIView that corresponds to and I can't find any documentation on the UIViewControllerWrapperView.

I am using the following code to swap the tab bars:

- (void)viewDidAppear:(BOOL)animated{ 
    [super viewDidAppear:animated];
    [AppHelpers hideTabBarController:self.tabBarController withHidden:YES];
    [self showCaptureTabBar];
}

+ (void) hideTabBarController:(UITabBarController *)tbc withHidden:(BOOL)hide {

    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:0.3];

    for(UIView *view in tbc.view.subviews)
    {       
        if([view isKindOfClass:[UIImageView class]])
        {
            if (hide) {
                [view setFrame:CGRectMake(view.frame.origin.x, 480, view.frame.size.width, view.frame.size.height)];
            } else {
                [view setFrame:CGRectMake(view.frame.origin.x, 431, view.frame.size.width, view.frame.size.height)];
            }
        }else {
            if (hide) {
                // When hiding the tabbarcontroller, the view should be full height
                [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 480)];
            } else {
                // When showing the tabbarcontroller, the view needs to leave 49px of room for it at the bottom
                [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 431)];
            }
        }
    }

    [UIView commitAnimations];  
}

- (void)showCaptureTabBar {
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:1];
    [captureTabBar setFrame:CGRectMake(captureTabBar.frame.origin.x, 412.0f, captureTabBar.frame.size.width, captureTabBar.frame.size.height)];
    [UIView commitAnimations];
}

Any ideas as to why the buttons could be disabled so I can try some other debugging would be greatly appreciated. Kinda hit a wall here


If your wrapper view is smaller that can definitely be causing the problem. Especially if the wrapper is smaller than all of the UI elements inside of it. UIViews can still show elements that extend beyond their frame but user interaction will not extend beyond their frame.

To see if this is the problem try setting the property of "Clip Subviews" to YES on the wrapper and see if you can still see the toolbar. If you can't see the toolbar then the wrapper should be made bigger so the whole toolbar can have user interaction.


What about doing the hide/show within a single beginAnimations/endAnimations context?

- (void)viewDidAppear:(BOOL)animated{ 
 [super viewDidAppear:animated];

 [UIView beginAnimations:@"firstAnimation" context:NULL];
 [UIView setAnimationDuration:0.3];
 [AppHelpers hideTabBarController:self.tabBarController withHidden:YES];

 [UIView beginAnimations:@"secondAnimation" context:NULL];
 [UIView setAnimationDuration:1.0];
 [self showCaptureTabBar];

 [UIView commitAnimations];
 [UIView commitAnimations];

}

Have you tried this? YOu should remove animations from the two methods, of course...

In this way we are nesting the two animations...

OLD ANSWER:

I don't know if this could help, but why don't you try to hide/show the subviews setting the hidden property?

        if (hide) {
            view.hide = YES;
        } else {
            view.hide = NO;
        }

Finally, if this does not work, a sort of hack (but I don't know if it works) could be the following: do the swap in viewWillAppear but do not call sequentially hideTabBarController and showCaptureTabBar; rather try and schedule the second method for execution with a 0 delay (this means that hideTabBarController is executed, then when the control flow gets back to the main loop, showCaptureTabBar is executed):

[AppHelpers hideTabBarController:self.tabBarController withHidden:YES];
[self performSelector:@selector(showCaptureTabBar) withObject:nil afterDelay:0];

Actually, since the hideTabBarController animation lasts 0.3 seconds, you could specify a delay of 0.3, just in case this do not work because the two animations interfere with one another.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜