10

これが私の状況です:
私はUINavigationController内部に aを持っていUITabBarControllerます。ナビゲーション コントローラーをドリルダウンすると、ある時点で非表示にUITabBarする必要があります。これは、ビューにできるだけ多くのスペースを確保するためです。push 内で
使用してそれを行いますが、非常にうまく機能します。ただ、以下の押したコントローラーで裏 を見せたい。他のコントローラーを入れようとしましたが、UITabBar が戻ってきません。self.hidesBottomBarWhenPushed = YESUIViewController
UITabBarself.hidesBottomBarWhenPushed = NO

ドキュメントに記載されているように、それは正常なようです:

hidesBottomBarWhenPushed

If YES, the bar at the bottom of the screen is hidden; otherwise, NO. If YES, the bottom bar remains hidden until the view controller is popped from the stack.

実際、このプロパティが yes に設定されたコントローラーがポップされると、タブバーが戻ってきます。

UITabBarコントローラーが非表示になったときに、コントローラーが押されたときに表示する適切な方法はありますか?

前もって感謝します

4

3 に答える 3

13

hidesBottomBarWhenPushed は非推奨ではありません。次の方法を使用して、UITabBar の非表示と表示を実現するのは非常に簡単であることがわかりました。

self.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:detailViewController animated:YES];
[detailViewController release];
self.hidesBottomBarWhenPushed = NO;

したがって、detailViewConroller をプッシュした直後に、非表示プロパティを NO にリセットする必要があります。このようにして、詳細ビューが戻ったときに再び表示されます。viewWillApear/disapear などに追加の変更を加える必要はありません。お楽しみください。

于 2012-07-15T13:08:56.907 に答える
7

さて、ここから先は非常に長い道のりです。

ドキュメントを読むと、デフォルトの動作は明らかです。ビュー コントローラのhides...プロパティが YES になると、ビュー コントローラがポップされるまでタブ バーが非表示になります。あなたが望んでいることはこれと直接矛盾しており、さまざまな理由から、最初にこのアプローチをとらないことをお勧めします.

ただし、実装が不可能というわけではありません。


  • プロパティhides...を NO に戻す

デフォルトの動作は変更できません。タブ バーを表示するには、スタック内のすべてのビュー コントローラーでhides...プロパティを NO に設定する必要があります。したがって、タブバーが非表示になっているビューから、新しいビューがプッシュされたときにバーを再度表示したい場合は、以前のビューコントローラーのhides...プロパティをNO再度設定する必要があります。

新しいView Controllerをプッシュする直前に、プロパティをNOに戻してください。

// ... prepare viewControllerToPush

self.hidesBottomBarWhenPushed = NO;
[self.navigationController pushViewController:viewControllerToPush animated:YES];
[viewControllerToPush release];

これにより、タブバーが再び表示されます。ただし、タブ バーは左から押し込まれ、新しいビューは右から押し込まれていることがわかります。これは明らかに望ましくないため、これを修正する必要があります。


  • タブ バーのレイヤー アクションのオーバーライド

つまり、タブバーが再び表示されるときに使用されるデフォルトのレイヤーアクション (アニメーション) は、左からのプッシュトランジションアニメーションです。UITabBar- (id < CAAction >)actionForLayer:(CALayer *)layer forKey:(NSString *)keyは、ケースの左からアニメーションを使用するように指示するメソッドを実装します。代わりに右からアニメーションを返すには、このメソッドをオーバーライドする必要があります。

positionタブ バーを元に戻すために、Cocoa はレイヤーのプロパティを変更します。したがって、新しいメソッドはキーの右側からアニメーションを返す必要がありposition、他のすべてのキーにはデフォルトの実装を使用する必要があります。positionタブバーへの使用は Apple によって文書化されていないため、次のバージョンでは予告なく変更される可能性があることに注意してください。いずれにせよ、Apple の仕様に真っ向から反するものを実装しているので、あまり文句を言うことはできません。

ただし、サブクラス化を使用してメソッドをオーバーライドすることはできません。UITabBar のカスタム サブクラスがあっても、デフォルトの UITabBar の代わりにそれを使用するように UITabBarController クラスを変更することはできないためです。

そのため、もう少し複雑になります。独自のロジックを UITabBar クラスに埋め込むには、メッセージの実装を「スワップ」する必要がありますactionForLayer: forKey:

まず、カテゴリを使用して UITabBar クラスに新しいメソッドを追加します。

@interface UITabBar(customAction)
@end

@implementation UITabBar(customAction)

- (id < CAAction >)customActionForLayer:(CALayer *)layer forKey:(NSString *)key {
    if ([key isEqualToString:@"position"]) {
        CATransition *pushFromRight = [[CATransition alloc] init];
        pushFromRight.duration = 0.25; 
        pushFromRight.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 
        pushFromRight.type = kCATransitionPush; 
        pushFromRight.subtype = kCATransitionFromRight;
        return [pushFromRight autorelease];
    } 
return [self defaultActionForLayer:layer forKey:key];
}
@end

そしてviewDidAppear、タブバーコントローラーのメソッドに以下のコードを挿入します。

Method original = class_getInstanceMethod([UITabBar class], @selector(actionForLayer:forKey:));
Method custom = class_getInstanceMethod([UITabBar class], @selector(customActionForLayer:forKey:));

class_replaceMethod([UITabBar class], @selector(actionForLayer:forKey:), method_getImplementation(custom), method_getTypeEncoding(custom));
class_addMethod([UITabBar class], @selector(defaultActionForLayer:forKey:), method_getImplementation(original), method_getTypeEncoding(original));

そうしないと、アプリケーションが最初に表示されたときにviewDidAppearタブバーviewDidLoadが右からスライドインするためです。

UITabBar インスタンスがメッセージを受け取るactionsForLayer forKey:と、カスタム メソッドcustomActionForLayer forKey:が呼び出されます。キーをインターセプトしposition、アニメーションを右から返します。別のキーの場合は、メッセージの元の実装を呼び出します。これは現在、メッセージに接続されていますdefaultActionsForLayer forKey:


わかりました。ビューをポップバックするときはhides...、新しいビューをプッシュするときにプロパティを NO に設定するため、プロパティを YES に戻す必要がある場合があることに注意してください (適切にアニメーション化するためにいくつかの同様のトリックを実行します)。

私はこれにしばらく時間を費やしましたが、皮肉なことに、*これを再度使用しないでください。Cocoa クラスの文書化されていない情報 (タブバーアニメーションの「位置」キー) を使用し、文書化された動作と矛盾し、反対しているためです。 Apple のヒューマン インターフェイス ガイドライン。アプリケーションが次の SDK バージョンでは同じように動作しない、ユーザーがインターフェイスを簡単に採用できない、または Apple が App Store でアプリケーションを拒否することさえあるかもしれません。

では、一体何に対する私の答えなのだろうか?ええと、iOS 開発に関するいくつかの興味深いトピックの例だと思います (そして、今日の私がひどく非生産的であることを示す証拠です:P)。

于 2011-02-22T04:48:38.847 に答える
6

iOS5でストーリーボードを使用する場合のこれに対する私のアプローチは次のとおりです。

プッシュセグエを実行する前に、hidesBottomBarWhenPushedプロパティをに設定します。NO

- (void)prepareForSegue:(UIStoryboardSegue*)segue sender:(id)sender
{
   if( [segue.identifier isEqualToString:@"PushDetailView"] )
   {
      self.hidesBottomBarWhenPushed = NO;
   }

   [super prepareForSegue:segue sender:sender];
}

セグエ識別子は明らかにあなた次第です。

YESビューコントローラのビューが消えたらすぐに戻すように設定します。

- (void)viewWillDisappear:(BOOL)animated
{
   self.hidesBottomBarWhenPushed = YES;

   [super viewWillDisappear:animated];
}

のすべての適切なアニメーションを使用して、チャームのように機能します(iOS 5.1でテスト済み)UITabBar

于 2012-07-27T10:32:05.520 に答える