提案された解決策のほとんどを試しました。結局、どれも私のために働いていませんでした。
hideTabBarWhenPushed は、次にプッシュされるビュー コントローラーだけでなく、プッシュされるすべてのビュー コントローラーのタブ バーを非表示にします。タブバーコントローラーを再表示したかった人のために。
Orafaelreis のソリューション (上記参照) は、それに最も適しているように見えました。しかし、彼の試みは厳密な縦向きでしか機能せず、上下逆さまでも機能しませんでした。だから私はそれを直さなければなりませんでした。これは私が最終的に得たものです:
#define kTabBarHeight 49 // This may be different on retina screens. Frankly, I have not yet tried.
- (void) hideTabBar:(BOOL)hide {
// fetch the app delegate
AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
// get the device coordinates
CGRect bounds = [UIScreen mainScreen].bounds;
float width;
float height;
// Apparently the tab bar controller's view works with device coordinates
// and not with normal view/sub view coordinates
// Therefore the following statement works for all orientations.
width = bounds.size.width;
height = bounds.size.height;
if (hide) {
// The tab bar should be hidden too.
// Otherwise it may flickr up a moment upon rotation or
// upon return from detail view controllers.
[self.tabBarController.tabBar setHidden:YES];
// Hiding alone is not sufficient. Hiding alone would leave us with an unusable black
// bar on the bottom of the size of the tab bar.
// We need to enlarge the tab bar controller's view by the height of the tab bar.
// Doing so the tab bar, although hidden, appears just beneath the screen.
// As the tab bar controller's view works in device coordinations, we need to enlarge
// it by the tab bar height in the appropriate direction (height in portrait and width in landscape)
// and in reverse/upside down orientation we need to shift the area's origin beyond zero.
switch (delegate.tabBarController.interfaceOrientation) {
case UIInterfaceOrientationPortrait:
// Easy going. Just add the space on the bottom.
[self.tabBarController.view setFrame:CGRectMake(0,0,width,height+kTabBarHeight)];
break;
case UIInterfaceOrientationPortraitUpsideDown:
// The bottom is now up! Add the appropriate space and shift the rect's origin to y = -49
[self.tabBarController.view setFrame:CGRectMake(0,-kTabBarHeight,width,height+kTabBarHeight)];
break;
case UIInterfaceOrientationLandscapeLeft:
// Same as Portrait but add the space to the with but the height
[self.tabBarController.view setFrame:CGRectMake(0,0,width+kTabBarHeight,height)];
break;
case UIInterfaceOrientationLandscapeRight:
// Similar to Upside Down: Add the space and shift the rect. Just use x and with this time
[self.tabBarController.view setFrame:CGRectMake(0-kTabBarHeight,0,width+kTabBarHeight,height)];
break;
default:
break;
}
} else {
// reset everything to its original state.
[self.tabBarController.view setFrame:CGRectMake(0,0,width,height)];
[self.tabBarController.tabBar setHidden:NO];
}
return;
}
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation{
// It is important to call this method at all and to call it here and not in willRotateToInterfaceOrientation
// Otherwise the tab bar will re-appear.
[self hideTabBar:YES];
// You may want to re-arrange any other views according to the new orientation
// You could, of course, utilize willRotateToInterfaceOrientation instead for your subViews.
}
- (void)viewWillAppear: (BOOL)animated {
// In my app I want to hide the status bar and navigation bar too.
// You may not want to do that. If so then skip the next two lines.
self.navigationController.navigationBar.barStyle = UIBarStyleBlackTranslucent;
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
[self hideTabBar: YES];
// You may want to re-arrange your subviews here.
// Orientation may have changed while detail view controllers were visible.
// This method is called upon return from pushed and pulled view controllers.
return;
}
- (void)viewWillDisappear: (BOOL)animated {
// This method is called while this view controller is pulled
// or when a sub view controller is pushed and becomes visible
// Therefore the original settings for the tab bar, navigation bar and status bar need to be re-instated
[self hideTabBar:NO];
// If you did not change the appearance of the navigation and status bar in viewWillAppear,
// then you can skip the next two statements too.
self.navigationController.navigationBar.barStyle = UIBarStyleBlack;
[[UIApplication sharedApplication] setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
return;
}
インライン コメントでは、各ステートメントの理由を説明する必要があります。ただし、それをコーディングするよりスマートな方法があるかもしれません。
ステータス バーとナビゲーション バーを非表示にすることにも関連する副作用が 1 つありますが、これは隠したくありません。1. このナビゲーション コントローラーから呼び出し元のナビゲーション コントローラーに戻るとき、呼び出し元のコントローラーのステータス バーとナビゲーション バーは、デバイスが 1 回回転するか、別のタブが前面に表示された後に関連するタブが再度選択されるまで重なります。2. 呼び出し元のビュー コントローラーがテーブル ビューであり、テーブルに戻るときにデバイスがランドスケープ モードの場合、テーブルはランドスケープに適した向きで表示されますが、縦向きのようにレイアウトされます。左上隅は問題ありませんが、一部のテーブル セルとタブ バーが画面の下に隠れています。右側に空きスペースがあります。これも、デバイスを再度回転させることで修正されます。
これらのマイナーだが厄介なバグの解決策を見つけたら、最新情報をお知らせします.