问题
How does one hide the UITabBar programmatically? It's been asked and answered multiple times on SO, but the answers seem to come in roughly two varieties:
1) Using a navigation controller, one can hide the next vc's tab bar before the push using hidesBottomBarWhenPushed property. Typical answer here.
2) Walk through the tabbar controller's view hierarchy and modify the tab bar's frame and/or visibility. Typical answer here.
But both sorts of answers fall short, imo. 1) What if we need to hide the tab bar on the view we are on, say when rotating to landscape. 2) A half page of code waking through an Apple library's private view hierarchy is a. cumbersome, b. prone to unforseen breaking, c. possibly a blocker for app approval.
So what's an app to do? Is the answer that it's not allowed? Is there an apple document ref supporting that? It would be a sad answer. Imo, the rotation case is a legitimate reason for hiding the tab bar.
Thanks in advance for your help.
回答1:
Sorry for the delayed response but I've pulled my code and you can see how I rotate my device to show a 'Map View' in full screen in landscape only.
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration {
if(toInterfaceOrientation == UIInterfaceOrientationLandscapeRight || toInterfaceOrientation == UIInterfaceOrientationLandscapeLeft) {
[self hideTabBar:self.tabBarController];
[self.view bringSubviewToFront:self.eventsMapView];
self.eventsMapView.bounds = self.view.bounds;
self.eventsMapView.frame = CGRectMake(0, -208, self.view.frame.size.width, 300);
} else if(toInterfaceOrientation == UIInterfaceOrientationPortraitUpsideDown || toInterfaceOrientation == UIInterfaceOrientationPortrait) {
[self showTabBar:self.tabBarController];
[self.view sendSubviewToBack:self.eventsMapView];
}
}
And since we call methods within that to actually hide and show the tab bar, we need to define those methods in our .m file as well:
#pragma mark - Tab Bar Methods -
-(void)hideTabBar:(UITabBarController *)tabbarcontroller {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
for(UIView *view in tabbarcontroller.view.subviews) {
if([view isKindOfClass:[UITabBar class]]) {
[view setFrame:CGRectMake(view.frame.origin.x, 480, view.frame.size.width, view.frame.size.height)];
} else {
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 480)];
}
}
[UIView commitAnimations];
}
-(void)showTabBar:(UITabBarController *)tabbarcontroller {
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.3];
for(UIView *view in tabbarcontroller.view.subviews) {
if([view isKindOfClass:[UITabBar class]]) {
[view setFrame:CGRectMake(view.frame.origin.x, 431, view.frame.size.width, view.frame.size.height)];
} else {
[view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 431)];
}
}
[UIView commitAnimations];
}
If you're already within a Tab Bar Controller then you need to make sure every child (or individual tab ViewController) returns TRUE for orientation like below.
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return TRUE;
}
Hope this helps - if you have any questions leave a comment and I'll update my answer to show it off better.
回答2:
You can find some useful code here. You can call hideTabbar from your shouldrotate: method
回答3:
2021 answer. Xcode 12. Create a new layout for when in Landscape mode. in the below picture, I created wAny hCompact (hC) attribute and then set it as hidden.
来源:https://stackoverflow.com/questions/12181935/hide-uitabbar-in-landscape