UITabBarController
を使用してモードを切り替えるアプリケーションがあります。特定のモードでは、そのモードのステップが完了するまでタブバーを非表示にしたいと思います。ナビゲーションコントローラーを使用していないため、ナビゲーションコントローラーでsetHidesBottomBarWhenPushed
メソッドを使用してタブバーを非表示にできないことに注意してください。
IOS 8より前のバージョンでtarbarを非表示にしようとすると:
self.tabBarController.tabBar.hidden = YES
タブバーはなくなりますが、タブバーがあった場所である画面の下部に50ピクセルの空白領域が残ります。その領域を埋める方法がわかりません。その領域にあるUIのすべてがクリップされ、表示されません。
これさえ可能ならどんなアイデアですか?ナビゲーションコントローラーに近づかないようにしたいです。
これが私のコードです:
もちろん、これはコントローラーのビュー階層でgoings onをいじくり回しています。変更/破損する可能性があります。これは定義済みのAPIを使用するため、Apple=は問題ではありませんが、コードの破壊については問題ではありません。
- (void)hideTabBar {
UITabBar *tabBar = self.tabBarController.tabBar;
UIView *parent = tabBar.superview; // UILayoutContainerView
UIView *content = [parent.subviews objectAtIndex:0]; // UITransitionView
UIView *window = parent.superview;
[UIView animateWithDuration:0.5
animations:^{
CGRect tabFrame = tabBar.frame;
tabFrame.Origin.y = CGRectGetMaxY(window.bounds);
tabBar.frame = tabFrame;
content.frame = window.bounds;
}];
// 1
}
- (void)showTabBar {
UITabBar *tabBar = self.tabBarController.tabBar;
UIView *parent = tabBar.superview; // UILayoutContainerView
UIView *content = [parent.subviews objectAtIndex:0]; // UITransitionView
UIView *window = parent.superview;
[UIView animateWithDuration:0.5
animations:^{
CGRect tabFrame = tabBar.frame;
tabFrame.Origin.y = CGRectGetMaxY(window.bounds) - CGRectGetHeight(tabBar.frame);
tabBar.frame = tabFrame;
CGRect contentFrame = content.frame;
contentFrame.size.height -= tabFrame.size.height;
}];
// 2
}
編集:匿名ユーザーが7.0の次の追加を提案しています(これはテストしていません。回避策か理想的な実装かはわかりません):
// 1. To Hide the black line in IOS7 only, this extra bit is required
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
[self.tabBarController.tabBar setTranslucent:YES];
}
// 2. For IOS 7 only
if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
[self.tabBarController.tabBar setTranslucent:NO];
}
編集:8.xでは完全にテストされておらず、一部のレイアウトでは不足している可能性があります。
スティーブのように、私はこれを行うためのきれいな方法を見つけていません(Apple Photopickerが同じようなことをしていますが)。これが私が行ったことです:
if (systemAction)
{
// Reveal tab bar back
CGRect bounds = [[UIScreen mainScreen] bounds];
CGRect tabBarFrame = self.tabBarController.tabBar.frame;
self.tabBarController.view.frame = CGRectMake(0,0,bounds.size.width,bounds.size.height);
self.toolBar.hidden = YES;
systemAction = NO;
}
else
{
//hide tab bar
CGRect bounds = [[UIScreen mainScreen] bounds];
CGRect tabBarFrame = self.tabBarController.tabBar.frame;
CGRect navigationBarFrame = self.navigationController.navigationBar.frame;
self.tabBarController.view.frame = CGRectMake(0,0,bounds.size.width,bounds.size.height+tabBarFrame.size.height);
self.toolBar.hidden = NO;
CGRect frame = self.toolBar.frame;
frame.Origin.y = bounds.size.height - frame.size.height - navigationBarFrame.size.height;
self.toolBar.frame = frame;
systemAction = YES;
}
これは、ビューを押し下げてツールバーを表示できるようにする(非表示にしない)ことです。明らかにこれは、タブバー+ナビゲーションコントローラーの「ルートビュー」のみを対象としています。後続のビューでは、プッシュしているビューコントローラーで 'hidesBottomBarWhenPushed'を設定できます。
上記のいくつかの解決策を試しましたが、iOS 8では喜びがありませんでした。viewWillAppearでの設定は、次のように機能します。その後、extendedLayoutIncludesOpaqueBarsが導入されたため、iOS 7で動作するはずです。
self.extendedLayoutIncludesOpaqueBars = true
self.tabBarController?.tabBar.isHidden = true
self.tabBarController?.tabBar.isOpaque = true
そして、viewWillDisappearで以下を使用するために離れるときに、tabBarsを再びオンにする必要がある場合。
self.tabBarController?.tabBar.isHidden = false
self.tabBarController?.tabBar.isOpaque = false
これを使用して、トランジションからの戻りを許可し、TabBar
を非表示にします。ボタンアクションでは使用しませんが、上記のように機能しない場合は、これがプログラム可能なソリューションの基礎になる可能性があります。
今日は少し遅いですが、今日の午後にトロールした質問に対するすべての回答のうち、これが私にとって最も効果的でした。
// Method call
[self hideTabBar:self.tabBarController];
// Method implementations
- (void)hideTabBar:(UITabBarController *) tabbarcontroller
{
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
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.5];
for(UIView *view in tabbarcontroller.view.subviews)
{
NSLog(@"%@", view);
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];
}
これを達成するために、この1行のみを使用します。タブバーを持つビューコントローラーを表示する前に、prepareForSegueメソッドを使用します。
-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{
if([segue.identifier isEqualToString:@"showLogin"]){
[segue.destinationViewController setHidesBottomBarWhenPushed:YES];
}
}
私はほとんど同じケースに取り組み、実際には http://www.developers-life.com/hide-uitabbarcontrolleruitabbar-with-animation.html のコードを使用し、私のニーズに応じてより良いものにしました、これは他の人にも役立つかもしれません。
私はルートビューコントローラーとしてUISplitViewControllerを使用しており、その詳細部分はUITabBarControllerです。ポートレートモードでタブバーを非表示にする必要がありました。
// In UITabBarController's custom implementation add following method,
// this method is all that will do the trick, just call this method
// whenever tabbar needs to be hidden/shown
- (void) hidetabbar:(NSNumber*)isHidden {
UITabBarController *tabBarController=self;
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:0.5];
CGRect tabbarFrame=CGRectZero;
for(UIView *theView in tabBarController.view.subviews) {
//NSLog(@"%@", view);
if([theView isKindOfClass:[UITabBar class]]) {
tabbarFrame=theView.frame;
if ([isHidden boolValue]) {
tabbarFrame=CGRectMake(tabbarFrame.Origin.x,
tabBarController.view.frame.size.height,
tabbarFrame.size.width,
tabbarFrame.size.height);
} else {
tabbarFrame=CGRectMake(tabbarFrame.Origin.x,
tabBarController.view.frame.size.height - tabbarFrame.size.height,
tabbarFrame.size.width,
tabbarFrame.size.height);
}
theView.frame=tabbarFrame;
break;
}
}
for(UIView *theView in tabBarController.view.subviews) {
if(![theView isKindOfClass:[UITabBar class]]) {
CGRect theViewFrame=theView.frame;
if ([isHidden boolValue]) {
theViewFrame=CGRectMake(theViewFrame.Origin.x,
theViewFrame.Origin.y,
theViewFrame.size.width,
theViewFrame.size.height + tabbarFrame.size.height);
} else {
theViewFrame=CGRectMake(theViewFrame.Origin.x,
theViewFrame.Origin.y,
theViewFrame.size.width,
theViewFrame.size.height - tabbarFrame.size.height);
}
theView.frame=theViewFrame;
}
}
[UIView commitAnimations];
}
次のコードを使用して、hidetabbar:メソッドを呼び出しました。
//In my UISplitViewController's custom implementation
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
@synchronized(self){
//change the self.splitDetailController to your UITabBarController's object
[self.splitDetailController
performSelector:@selector(hidetabbar:)
withObject:[NSNumber numberWithBool:UIInterfaceOrientationIsLandscape(interfaceOrientation)]
afterDelay:0.5];
}
return YES;
}
このコードをシミュレータでのみ動作するようにテストしました。デバイスでも動作するかどうか教えてください;-)
タブバーのカテゴリーを作成し、簡単に表示/非表示にすることができます。フルビューにアクセスできます。
カテゴリを作成#import "UITabBarController+HideTabBar.h"
@implementation UITabBarController (HideTabBar)
- (void)hideTabBarAnimated:(BOOL)animated
{
CGRect statusbarFrame = [UIApplication sharedApplication].statusBarFrame;
CGRect tabBarControllerFrame = self.view.frame;
if (statusbarFrame.size.height>20)
{
tabBarControllerFrame.size.height = screenSize.size.height + self.tabBar.frame.size.height - 20.0;
}
else
{
tabBarControllerFrame.size.height = screenSize.size.height + self.tabBar.frame.size.height ;
}
if (animated) {
[UIView animateWithDuration:0.2 animations:^{
[self.view setFrame:tabBarControllerFrame];
} completion:^(BOOL finished) {
}];
}
else
[self.view setFrame:tabBarControllerFrame];
}
- (void)showTabBarAnimated:(BOOL)animated {
CGRect statusbarFrame = [UIApplication sharedApplication].statusBarFrame;
CGRect tabBarControllerFrame = self.view.frame;
if (statusbarFrame.size.height>20)
{
tabBarControllerFrame.size.height = screenSize.size.height - 20.0;
}
else
{
tabBarControllerFrame.size.height = screenSize.size.height ;
}
if (animated) {
[UIView animateWithDuration:0.2 animations:^{
[self.view setFrame:tabBarControllerFrame];
} completion:^(BOOL finished) {
}];
}
else
[self.view setFrame:tabBarControllerFrame];
}
@end
注:use statusbarFrame
は、hotspotまたはcallがオンになっているので、タブバーはカットされません。
次に、メソッドを使用するクラスをインポートするカテゴリをインポートし、以下のメソッドを呼び出してタブバーを表示または非表示にします。
[self.tabBarController hideTabBarAnimated:YES];
[self.tabBarController showTabBarAnimated:YES];
お役に立てれば。
自動サイズ変更マスクには列挙があります。すべてのオプションを設定して、親ビューでサブビューの自動サイズ変更オプションがオンになっているかどうかを確認してください
これがうまくいくことを願っています。
@ interface UITabBarController(Additions) -(void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated; @ end @ implementation UITabBarController(Additions) -(void)setTabBarHidden:(BOOL)hidden animated:(BOOL)animated { if(animated) { [UIView beginAnimations:nil context:nil]; } if(hidden) { self.tabBar.frame = CGRectMake(self.tabBar.frame.Origin.x、self.tabBar.superview.frame.size.height、self.tabBar.bounds.size.width、self .tabBar.bounds.size.height); } else { self.tabBar.frame = CGRectMake(self.tabBar.frame.Origin.x 、self.tabBar.superview.frame.size.height-self.tabBar.frame.size.height + 10、self.tabBar.bounds.size.width、self.tabBar.bounds.size.height); } if(アニメーション) { [UIView commitAnimations]; } }
元のアーキテクチャを維持する明白な解決策は、そのビューをモーダルに提示することでした。
- (void)tabBarController:(UITabBarController *)tb
didSelectViewController:(UIViewController *)vc {
if (tb.selectedIndex == MODALONE) {
UIViewController* mod =
[[UIViewController alloc] initWithNibName: @"ModalView"
bundle: nil];
[tb presentModalViewController:mod animated:NO];
[mod release];
}
}
ビューは現在、タブバーを含む画面全体(ステータスバーがある場合を除く)をカバーしているため、ユーザーがそのタブバー項目を押すと、タブバーが消えたように見えます。
これが私の解決策です(私のタブビューコントローラは適切なナビゲーションコントローラの内側にあります)...したがって、UITabBarControllerをサブクラス化してこれを行いました... -setTabBarHidden:
方法
- (void)setTabBarHidden:(BOOL)hidden {
_tabBarHidden = hidden;
[UIView performWithoutAnimation:^{
[self adjustViews];
}];
}
- (void)adjustViews {
if ( _tabBarHidden ) {
CGRect f = self.tabBar.frame;
// move tab bar offscreen
f.Origin.y = CGRectGetMaxY(self.view.frame);
self.tabBar.frame = f;
// adjust current view frame
self.selectedViewController.view.frame = self.view.frame;
} else {
CGRect f = self.tabBar.frame;
// move tab bar on screen
f.Origin.y = CGRectGetMaxY(self.view.frame) - (CGRectGetMaxY(self.tabBar.bounds) + CGRectGetMaxY(self.navigationController.navigationBar.frame));
self.tabBar.frame = f;
// adjust current view frame
f = self.view.bounds;
f.size.height -= CGRectGetMaxY(self.tabBar.bounds);
self.selectedViewController.view.frame = f;
}
}
- (void)viewWillLayoutSubviews {
[super viewWillLayoutSubviews];
[UIView performWithoutAnimation:^{
[self adjustViews];
}];
}
- (void)viewDidLayoutSubviews {
[super viewDidLayoutSubviews];
[UIView performWithoutAnimation:^{
[self adjustViews];
}];
}
ステートメントをUIViewControllerのinitメソッドに入れます
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
self.hidesBottomBarWhenPushed = true
setupDependencyConfigurator()
}
サブビューにautoResizingMaskが設定されていますか?
view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
そのような何かはトリックを行い、スタックの上にあるビューのサイズを変更できるようにする必要があります。