IOS 8に追加された新しい機能を使用しようとしています-ユーザーがテーブルビューをスクロールしている間はナビゲーションバーを非表示にします(モバイルSafariの場合と同様)。 hidesBarsOnSwipe
のプロパティUINavigationController
をYES
のviewDidAppear
メソッドでUITableViewController
に設定しています:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if([self.navigationController respondsToSelector:@selector(hidesBarsOnSwipe)]) {
self.navigationController.hidesBarsOnSwipe = YES;
}
}
ビューがスクロールされると、ナビゲーションバーが非表示になります。ここまでは順調ですね。しかし、ステータスバーはまだ表示されており、テーブルビューの内容はそれを通して見えますが、見苦しいです:
edgesForExtendedLayout
をUIEdgeRectNone
に設定するか、Table ViewのcontentInset
を調整しようとしましたが、役に立ちませんでした。ナビゲーションバーとともにステータスバーを非表示にする、または不透明にする他のソリューションはありますか?
Anasの答えを基に、実用的なソリューションがあります(tableViewController
がUITableViewController
インスタンスであると仮定しています):
UINavigationController
サブクラス(または潜在的にtableViewController
からも):
- (void)viewDidLoad {
if ([self respondsToSelector:@selector(barHideOnSwipeGestureRecognizer)]) {
// iOS 8+
self.hidesBarsOnSwipe = YES;
[self.barHideOnSwipeGestureRecognizer addTarget:self action:@selector(swipe:)];
}
}
- (void)swipe:(UISwipeGestureRecognizer *)recognizer {
BOOL shouldHideStatusBar = self.navigationController.navigationBar.frame.Origin.y < 0;
tableViewController.hideStatusBar = shouldHideStatusBar;
[UIView animateWithDuration:0.2 animations:^{
[tableViewController setNeedsStatusBarAppearanceUpdate];
}];
}
tableViewController
で:
@property(nonatomic, getter = shouldHideStatusBar) BOOL hideStatusBar;
- (BOOL)prefersStatusBarHidden {
return [self shouldHideStatusBar];
}
これがうまくいかない場合はお知らせください。いくつかの非自明なこと:
self.navigationController.navigationBar.frame.Origin.y
は、非表示の場合は-44(ナビゲーションバーの負の高さ)、表示の場合は20(ステータスバーの高さ)でした。アニメーションの間でも中間にはなかったため、負の値==非表示および非負の値==が表示されます。UIViewController
内のUINavigationController
内にUITabBarController
があり、prefersStatusBarHidden
でUIViewController
をオーバーライドするまで機能しませんでした。setNeedsStatusBarAppearanceUpdate
の呼び出しをラップしない限り、コンテンツは20ポイント上昇する可能性があります。実際、それは非常に簡単です。ナビゲーションisNavigationBarHiddenプロパティをステータスバーに接続するだけです。
Objective-C
- (BOOL)prefersStatusBarHidden {
return self.navigationController.isNavigationBarHidden;
}
Swift <= 2.
override func prefersStatusBarHidden() -> Bool {
return navigationController?.navigationBarHidden ?? false
}
Swift 3.
override var prefersStatusBarHidden: Bool {
return navigationController?.isNavigationBarHidden ?? false
}
また、アプリケーションの.plistファイルに「View Controller-based status bar Appearance」=「YES」があることを確認してください。
その新しいプロパティにはbarHideOnSwipeGestureRecognizer
が付いています。
INavigationController Class Reference から:
必要に応じてジェスチャレコグナイザーに変更を加えることができますが、デリゲートを変更してはなりません。また、デフォルトのターゲットオブジェクトと、それに設定されているアクションを削除しないでください。プロパティをオーバーライドしてこのジェスチャ認識機能を置き換えようとしないでください。
ただし、ターゲットをaddできます:
[self.navigationController setHidesBarsOnSwipe:YES];
[self.navigationController.barHideOnSwipeGestureRecognizer addTarget:self action:@selector(swipeGesture:)];
...そして、コールバックであなたがやりたいことをします:
- (void)swipeGesture:(UIPanGestureRecognizer*)gesture
{
// Tweak the status bar
}
ジェスチャの状態を手動で切り替えたり、ステータスバーを非表示/表示するタイミングを見つけたりする必要があるかもしれません。
@iOSergeyからの答えは完璧に機能します!
Swift 1.2のソリューションを次に示します。次のコードをビューの.Swiftファイルに追加します。
override func prefersStatusBarHidden() -> Bool {
return self.navigationController!.navigationBarHidden as Bool
}
アニメーションでステータスバーを非表示にする場合:
override func preferredStatusBarUpdateAnimation() -> UIStatusBarAnimation {
return .Slide
}
override func prefersStatusBarHidden() -> Bool {
return navigationController?.navigationBarHidden ?? false
}
多くの苦労の末、ようやくこれを解決することができました。
次のコードをUIViewControllerのviewDidLoad関数に追加します。
//ステータスバーの無地の背景を作成(in Swift Code)
let statusFrame = CGRectMake(0.0、0、self.view.bounds.size.width、
UIApplication.sharedApplication()。statusBarFrame.size.height)var statusBar = UIView(frame:statusFrame)
statusBar.backgroundColor = UIColor.whiteColor()
self.view.addSubview(statusBar)
あなたがしているのは、ナビゲーションバーのすぐ下に実線のバーを作成することです。ナビゲーションバーが上に移動すると、ソリッドバーも上に移動し、ステータスバーのすぐ後ろに移動します。
唯一の問題は、画面を横向きに回転させると、ステータスバーが消えても白いバーがそこにあることです。
OK barHideOnSwipeGestureRecognizer
があります。したがって、対応するUIPanGesture
のリスナーを作成できます。ナビゲーションバーが非表示の場合、そのy Originは-44.0であることに注意してください。それ以外の場合は0です(ステータスバーを非表示にしているため、20ではありません!)。
View Controller(Swift 2)で:
// Declare at beginning
var curFramePosition: Double!
var showStatusBar: Bool = true
self.navigationController?.barHideOnSwipeGestureRecognizer.addTarget(self, action: "didSwipe:")
...
override func viewDidLoad(){
self.navigationController?.hidesBarsOnSwipe = true
curFramePosition = 0.0 // Not hidden
self.navigationController?.barHideOnSwipeGestureRecognizer.addTarget(self, action: "didSwipe:")
...
}
func didSwipe(swipe: UIPanGestureRecognizer){
// Visible to hidden
if curFramePosition == 0 && self.navigationController?.navigationBar.frame.Origin.y == -44 {
curFramePosition = -44
showStatusBar = false
prefersStatusBarHidden()
setNeedsStatusBarAppearanceUpdate()
}
// Hidden to visible
else if curFramePosition == -44 && self.navigationController?.navigationBar.frame.Origin.y == 0 {
curFramePosition = 0
showStatusBar = true
prefersStatusBarHidden()
setNeedsStatusBarAppearanceUpdate()
}
}
override func prefersStatusBarHidden() -> Bool {
if showStatusBar{
return false
}
return true
}
別の方法は、別のビュー(tableviewまたはcollectionviewまたはwebviewまたはscrollviewなど)を追加し、ビューの上部の制約を「Superview.Top」に、下部の制約を「Top Layout Guide.Bottom」に設定するだけです。ビューの背景色とthats、それはあなたもコードなしでInterface Builderでそれをすべて行うことができます。また、そのイベントに応答する場合は、ビューの境界変更にキーパスオブザーバーを追加するか、ビューをサブクラス化してその境界セッターをオーバーライドできます...
ナビゲーションisNavigationBarHiddenプロパティをステータスバーに接続する必要があります。
return self.navigationController.isNavigationBarHidden;