これは解決するのが楽しいものでした。
これは非常に簡単なはずです。UIView transitionWithView
パブリック API で設定されているように、ナビゲーション バーの非表示状態と非表示状態の間でクロスフェードを実行するために使用しますsetNavigationBarHidden:animated:
。実際、これはナビゲーションバーの「フェードアウト」には機能しますが、フェードインには問題がありました。問題は、 がアニメーション化可能なプロパティ (例: )UIView +transitionWithView:
をアニメーション化しないにもかかわらず、 を指定しない限り、ナビゲーション バーが所定の位置にスライドすることでした。 frame
UIViewAnimationOptionAllowAnimatedContent
私には、 の呼び出しでアニメーション化が指定されているかどうかに関係なく、内部的に がアニメーション ブロック内で をUINavigationController
再配置することがわかります。が に設定されている場合、このアニメーション ブロックの持続時間はおそらく '0' に設定されます。UINavigationBar
setNavigationBarHidden:animated:
animate:
NO
解決策は、クロス フェード トランジションの前にナビゲーション バーを表示 (アニメーションなし) に設定することです。これにより、ナビゲーション バーが正しい位置でクロス フェードを開始し、クロス フェードが新しい非表示の状態のみを明らかにすることが保証されます。
私のサンプル プロジェクトは、標準のシングル ビュー アプリケーションです。ストーリーボードUINavigationController
には、エントリ ポイントである があります。このコントローラーのバーのスタイルUINavigationBar
を黒半透明に設定しました (写真アプリと同様)。ナビゲーション コントローラーは、境界全体を埋めるrootViewController
単純なものです (これも写真アプリと同様です)。ビューコントローラーで次のコードを呼び出すために、ビューにを追加しました。UIViewController
UIImageView
UITapGestureRecognizer
- (IBAction) onShowHideNavbar: (id) sender
{
BOOL hide = !self.navigationController.navigationBarHidden;
if ( !hide)
{
[self.navigationController setNavigationBarHidden: hide animated: NO];
}
[UIView transitionWithView: self.navigationController.view
duration: 1
options: UIViewAnimationOptionTransitionCrossDissolve
animations: ^{
[self.navigationController setNavigationBarHidden: hide animated: NO];
}
completion: nil ];
}
以上のことから、直接の隠しプロパティまたはアルファ プロパティをいじっても問題 (Apple Rejection) が発生することはないと思いますUINavigationBar
。これらは UINavigationController によって管理されており、変更すると目に見えない結果が生じる可能性があるため、ドキュメントではこれらに触れないように警告しています。しかし、私の意見では、それらはパブリック API であり、それらを使用することは拒否の原因となるべきではありません。