さて、ここから先は非常に長い道のりです。
ドキュメントを読むと、デフォルトの動作は明らかです。ビュー コントローラのhides...
プロパティが YES になると、ビュー コントローラがポップされるまでタブ バーが非表示になります。あなたが望んでいることはこれと直接矛盾しており、さまざまな理由から、最初にこのアプローチをとらないことをお勧めします.
ただし、実装が不可能というわけではありません。
デフォルトの動作は変更できません。タブ バーを表示するには、スタック内のすべてのビュー コントローラーで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)。