ビューの1つでUINavigationBar
階層の一部ではないカスタムUINavigationController
を使用したい。 UINavigationBar
をStoryboardにドラッグすると、次のように表示されます。
このバーは44ピクセルです。これは、ステータスバーがこのスペースを共有しない場合に十分です。 iOS7では、ステータスバーのスペースを含む画面全体を使用できるため、UINavigationBar
の高さは44ピクセルではなく64ピクセルにする必要があります。
ビューをUINavigationController
の階層に接続すると、正しいことが表示されます。
ifUINavigationBar
のプロパティbarPosition:
がUIBarPositionTopAttached
に設定されている場合、バーは64pxになります。ただし、これはreadonly
-プロパティです。
私の検索結果には、「回避策」と思われるものだけが表示されています。このUINavigationController
の前に無用のUIViewController
を追加することにより、階層を持っているふりをすることができ、UINavigationBar
を64pxで自動的に追加します。
本当に 64pxをカバーする '不正'(ナビゲーションコントローラーの助けなしで)UINavigationBar
を使用する方法はありませんか?その場合、その理由に関して正当な理由はありますか?
(デフォルトではUINavigationBar
が64pxであるべきだと言っているわけではありませんが、インスペクターにオプションがあるはずです)
(これを解決するためのプログラム的な方法で答える人もいます。これらの答えは機能しますが、それでもストーリーボードをdesignする必要があります。 (ギャップ)。これをストーリーボードで設定できるかどうか、または許可されない理由を知りたいのですが。)
プロパティbarPosition
をUIBarPositionTopAttached
に別の方法で設定できます!
デリゲートクラスに-positionForBar:
を実装します。
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
{
return UIBarPositionTopAttached;
}
ナビゲーションバーの上部も上部レイアウトガイドに固定する必要があります。
ナビゲーションバーの高さをプログラムで変更できます。
[navBar setFrame:CGRectMake(0, 0, 320, 64)];
編集:コメントで書いたように、自動レイアウトを回避するためにviewDidLayoutSubviews
にこの行を入れる必要があるかもしれません。
Interface Builderの「Identity Inspector」の「User Defined Runtime Attributes」を使用して、ビューの上部にアタッチするように設定できます。 barPosition
プロパティを設定します。
barPosition
プロパティのドキュメントは次のとおりです。 https://developer.Apple.com/library/ios/documentation/uikit/reference/UIBarPositioning_Protocol/Reference/Reference.html
UINavigationController
を使用するか、プログラムで設定することなく、これを実現する方法があります。ナビゲーションバーの高さの制約を任意の値(この場合は64)に設定するだけです。
同じことをプログラムで次のように達成できます。
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:navigationBar attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1 constant:64.0f]];
編集:
@ nerdist-colonyが指摘したように、Autolayoutを使用するときは、常にtranslatesAutoresizingMaskIntoConstraints
をNO
に設定する必要があります。そうしないと、制約に矛盾が生じる可能性があります。
私はスタンドアロンのUINavigationBarも使用していますが、同じ問題が発生しました。これを適切に修正する方法は2つあります。
制約と親UIViewを使用して修正しました。ストーリーボードのこのUIViewを、{0、0、320、64}フレームのUINavigationBarの親ビューとして設定します。 UINavigationBarに必要なサイズを強制する制約または制約のセットを追加できます。また、親UIViewのストーリーボードに正しいフレームがある場合、ストーリーボードの他のビューを通常どおりレイアウトできます。
これで、自動レイアウトが無効になっている場合、リンジーの答えで説明されているように、プログラムでバーの高さを変更できます。 -(void)viewDidLayoutSubviews
はそれを行うのに適した場所のようです。
Autolayoutを使用する場合、UINavigationBarの制約の高さを64以上のイベントに設定できます。
最小限のコード介入でこれを行う方法を詳しく説明したブログ記事を書きました。バーはストーリーボードにギャップを表示しますが、デバイスでは正常に機能します。要するに、手順は次のとおりです。
1)ストーリーボードのView Controllerにナビゲーションバーを追加します。
2)ストーリーボードのナビゲーションバーの制約を設定します。
-Navigation Bar.Top = Top Layout Guide.Bottom
-Navigation Bar.Leading = Superview.Leading
-Navigation Bar.Trailing = Superview.Trailing
3)ストーリーボードのナビゲーションバーを@IBOutletとしてView Controllerに接続します。
4)View Controllerのクラスで、クラス宣言にUINavigationBarDelegateプロトコルを追加します。
5)View ControllerのviewDidLoadメソッドで、Navigation Barのデリゲートをselfに設定します。
6)View Controllerで、バーポジショニングデリゲートのpositionForBarメソッドを追加します。 TopAttachedを表すUIBarPositionを返します。 (注:UINavigationBarDelegateはUIBarPositioningDelegateからこのメソッドを継承します。)
GIF画像の完全な投稿はこちらです:
対応するNavigation ControllerなしでNavigation Barを簡単に使用
これらの手順は、Swift 2.1/Xcode 7.2以降で機能します
@startupThekid:
uINavigationControllerによって管理されているUINavigationBarの自動サイズ変更マスクを変更しようとすると、iOSは例外を生成します。
ただし、投稿したObjective Cコードに相当するSwiftは次のとおりです。
var navBar = self.navigationController!.navigationBar
in viewDidAppear():
navBar.setTranslatesAutoresizingMaskIntoConstraints = false
制約を設定する必要がある場合:
var navBarHeightConstraint =
NSLayoutConstraint(item: navBar, attribute: .Height,
relatedBy: .Equal, toItem: nil,
attribute: .Height, multiplier: 1, constant: height)
self.view.addConstraint(navBarHeightConstraint)
その後、必要に応じて、デバイスの向きの変更など、ナビゲーションバーの高さを変更するために、制約の定数プロパティを変更できるはずです
私は同じ船に乗っていて問題を抱えていましたが、今では修正しました。フレームを明示的に設定することを避けるために正しいことをしようとしています。これは、さまざまなデバイスサイズの将来の保証と簡単なサポートに望ましいものです。私の場合、ナビゲーションバーの下にWebビューが必要です。
ser3269713's answer のように、View ControllerをUINavigationBarDelegate
に設定し、positionForBar:
を実装してUIBarPositionTopAttached
を返します。他のトリックは、自動レイアウトを使用してtopLayoutGuideの下にバーを配置することであるように思えました。
これはナビゲーションバーとWebviewをプログラムで作成した後、viewDidLoad
で使用していたコードでしたが、バーが高さ44で止まっているのが見えました。しかし、すぐに理由を見ることができませんでした:
[navigationBar sizeToFit];
navigationBar.delegate = self;
[self.view addSubview:navigationBar];
[self.view addSubview:webView];
id guide = self.topLayoutGuide;
NSDictionary *viewNamesDict = NSDictionaryOfVariableBindings(webView, navigationBar, guide);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[webView]|" options:0 metrics:nil views:viewNamesDict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[guide][navigationBar][webView]|" options:0 metrics:nil views:viewNamesDict]];
しかし、私はさらにいくつかのことを考えて自動レイアウトをいじりましたが、それだけで私の問題の原因であることがわかりました。自動サイズ変更マスクからナビゲーションバーの翻訳された制約に依存しようとしていましたが、明示的に定義する必要があることがわかりました。動作する新しいviewDidLoad
コードを次に示します。
[navigationBar sizeToFit];
navigationBar.delegate = self;
navigationBar.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:navigationBar];
[self.view addSubview:webView];
id guide = self.topLayoutGuide;
NSDictionary *viewNamesDict = NSDictionaryOfVariableBindings(webView, navigationBar, guide);
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[navigationBar]|" options:0 metrics:nil views:viewNamesDict]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[webView]|" options:0 metrics:nil views:viewNamesDict]];
NSString *verticalLayoutVisualExpression = [NSString stringWithFormat:@"V:|[guide][navigationBar(%f)][webView]|", navigationBar.frame.size.height];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:verticalLayoutVisualExpression options:0 metrics:nil views:viewNamesDict]];
そして、はい、私が望んでいたように、これは横向きになると自動的にバーを移動し、ステータスバーは非表示になります。
(レイアウトコードをより簡潔にするMasonryのような自動レイアウトヘルパーを心からお勧めします。1つは、MasonryがtranslatesAutoresizingMaskIntoConstraints
をオフにしてくれます)
これは非常にハッキーな方法ですが、私にとってはうまくいきました。 NavigationViewController
があり、上部に[完了]ボタンと[キャンセル]ボタンがあるUINavigationBar
があるViewControllerをモーダルにロードしたい。これは次のように見えました:
ご覧のとおり、UINavigationBar
と同じ色にしたい上部に白い帯があります。 UINavigationBar
の高さをプログラムで変更する代わりに、新しいビューを作成し、その背景色をUINavigationBar
(HEX = F8F8F8、RGBA = 248,248,248,1.0)に設定しました。繰り返しになりますが、これは非常にハッキーです。これが今の様子です