web-dev-qa-db-ja.com

プログラムでナビゲーションバーの高さを取得する

より多くのView Controller(ナビゲーションバー)が存在すると、UIViewがその高さで押し下げられることがわかります。また、この高さ= 44pxであることも知っています。また、このプッシュダウンが[self.view].frame.Origin.y = 0を保持していることも発見しました。

それでは、定数に設定するだけでなく、このナビゲーションバーの高さをどのように決定しますか?

または、短いバージョンでは、UIViewがナビゲーションバーを上にして表示されていることをどのように判断しますか?


電球が点灯し始めました。残念ながら、以下に説明するように、問題を修正する統一的な方法を発見していません。

私の問題はすべて自動サイズ変更マスクに集中していると思います。そして、私が結論した理由は、UIWebViewの有無にかかわらず同じ症状が存在するからです。そして、その症状は、すべてがポートレートにとって桃色であるということです。横向きの場合、一番下のUIButtonがTabBarの後ろにポップダウンします。

たとえば、1つのUIViewには、上から下に:

UIView –スプリングセット(デフォルトケース)とストラットなし

UIScrollView-2つのスプリングを設定し、他のすべて(UIViewなど)をクリアすると、UIButtonはそのすぐ上のオブジェクトに侵入します。すべてをクリアすると、UIButtonはOKになりますが、一番上にあるものはStatusBarの後ろに隠れてしまいます。

UILabelとUIImageが次に垂直に-トップストラットセット、どこでも柔軟

UIWebViewを持っている少数の人々のために写真を完成させるためだけに:

UIWebView-Struts:上、左、右Springs:両方

UIButton –設定なし、つまりどこでも柔軟

私の電球は暗いですが、希望があるようです。


私は短いコメントのコメントを提供するよりも多くのスペースが必要だったので、我慢してください。

私が本当に釣りをしているものを理解しようとしてくれてありがとう...だからここに行きます。

1)各UIViewController(TabBarアプリ)には、UIImage、テキストなどがあります。別の共通点は、下部のUIButtonです。 UIViewControllersのいくつかでは、UIButtonの上にUIWebViewがあります。

したがって、UIImage、テキストなどUIWebView(一部)UIButton

上記のすべてを囲むのがUIScrollViewです。

2)UIWebViewがある場合、そのautoresizingMaskは次のようになります。

   —
   |
   —

   ^
   |
   |

| — | ←----→| — | | | V UIButtonのマスクには何も設定されていません。つまり、どこでも柔軟です

-viewDidLoad内で、-repositionSubViewsを呼び出して、その中で以下を実行します。

UIWebViewがない場合、IBで配置したUIButtonを中央に配置する以外は何もしません。

UIWebViewがある場合、その* content * Heightを決定し、コンテンツ全体を囲むようにフレームを設定します。

UIScrollView *scrollViewInsideWebView = [[webView_ subviews] lastObject];
webViewContentHeight = scrollViewInsideWebView.contentSize.height;
[webView_ setFrame:CGRectMake(webViewOriginX, webViewOriginY,
                          sameWholeViewScrollerWidth, webViewContentHeight)]

それを行ったら、プログラムでUIButtonを押し下げて、UIWebViewの下に配置します。

縦から横に回転するまで、すべてが機能します。

-didRotateFromInterfaceOrientation内で-repositionSubViewsを呼び出します。

UIWebViewのコンテンツの高さが回転しても変わらないのはなぜですか?.

ポートレートからランドスケープまで、コンテンツの幅は拡大し、コンテンツの高さは縮小します。 NSLogに応じてではありませんが、視覚的には正常に機能します。

とにかく、UIWebViewの有無にかかわらず、私が説明したボタンは、LandscapeモードではTabBarの下に移動しますが、スクロールして表示されることはありません。 「激しく」スクロールするとTabBarの後ろに表示されますが、TabBarの後ろに「フォールバック」します。

結論として、TabBarはUIViewの下部に配置され、NavigationBarはUIViewを押し下げるため、TabBarとNavigationBarの高さについて尋ねたのはこの最後の理由です。

さて、ここでコメントを1つまたは2つ追加します。これは、それらが意味をなさないためです。

UIWebViewがないため、すべてをIBから見たままにしておきます。

UIWebViewを使用して、UIWebViewのframe.heightをcontentHeightに増やし、すべてのサブビューを囲む周囲のUIScrollViewの高さを上方に調整します。

さて、あなたはそれを持っています。

116
John Love

電球が点灯し始めました。残念ながら、以下に説明するように、問題を修正する統一的な方法を発見していません。

私の問題はすべて自動サイズ変更マスクに集中していると思います。そして、私が結論した理由は、UIWebViewの有無にかかわらず同じ症状が存在するからです。そして、その症状は、すべてがポートレートにとって桃色であるということです。横向きの場合、一番下のUIButtonがTabBarの後ろにポップダウンします。

たとえば、1つのUIViewには、上から下に:

IView –スプリングが設定され(デフォルトの場合)、ストラットなし

IScrollView-2つのスプリングを設定し、他のすべて(UIViewなど)をクリアすると、UIButtonはそのすぐ上のオブジェクトに侵入します。すべてをクリアすると、UIButtonはOKになりますが、一番上にあるものはStatusBarの後ろに隠れてしまいます。

ILabelおよびUIImage次の垂直方向–トップストラットセット、他のどこでも柔軟

UIWebViewを持っている少数の人々のために写真を完成させるためだけに:

IWebView-Struts:上、左、右Springs:両方

IButton –設定なし、つまりどこでも柔軟

私の電球は暗いですが、希望があるようです。

1
John Love

このようなことをしますか?

    NSLog(@"Navframe Height=%f",
        self.navigationController.navigationBar.frame.size.height);

Swiftバージョンは ここにあります

238
Sum

IPhone-Xでは、トップバー(ナビゲーションバー+ステータスバー)の高さが変更されます(増加します)。

トップバー(ナビゲーションバーとステータスバーの両方)の正確な高さが必要な場合は、これを試してください。

Objective-C

CGFloat topbarHeight = ([UIApplication sharedApplication].statusBarFrame.size.height +
       (self.navigationController.navigationBar.frame.size.height ?: 0.0));

Swift 4

let topBarHeight = UIApplication.shared.statusBarFrame.size.height +
        (self.navigationController?.navigationBar.frame.height ?? 0.0)

簡単に、このUIViewController拡張機能を試してください

extension UIViewController {

    /**
     *  Height of status bar + navigation bar (if navigation bar exist)
     */

    var topbarHeight: CGFloat {
        return UIApplication.shared.statusBarFrame.size.height +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
    }
}

Swift

let topBarHeight = UIApplication.sharedApplication().statusBarFrame.size.height +
(self.navigationController?.navigationBar.frame.height ?? 0.0)
66
Krunal

Swiftバージョン:

let navigationBarHeight: CGFloat = self.navigationController!.navigationBar.frame.height
57
King-Wizard

これを試しましたか?

let barHeight = self.navigationController?.navigationBar.frame.height ?? 0
6
Keaz
UIImage*image = [UIImage imageNamed:@"logo"];

float targetHeight = self.navigationController.navigationBar.frame.size.height;
float logoRatio = image.size.width / image.size.height;
float targetWidth = targetHeight * logoRatio;

UIImageView*logoView = [[UIImageView alloc] initWithImage:image];
// X or Y position can not be manipulated because autolayout handles positions.
//[logoView setFrame:CGRectMake((self.navigationController.navigationBar.frame.size.width - targetWidth) / 2 , (self.navigationController.navigationBar.frame.size.height - targetHeight) / 2 , targetWidth, targetHeight)];
[logoView setFrame:CGRectMake(0, 0, targetWidth, targetHeight)];
self.navigationItem.titleView = logoView;

// How much you pull out the strings and struts, with autolayout, your image will fill the width on navigation bar. So setting only height and content mode is enough/
[logoView setContentMode:UIViewContentModeScaleAspectFit];

/* Autolayout constraints also can not be manipulated since navigation bar has  immutable constraints
self.navigationItem.titleView.translatesAutoresizingMaskIntoConstraints = false;

NSDictionary*metricsArray = @{@"width":[NSNumber numberWithFloat:targetWidth],@"height":[NSNumber numberWithFloat:targetHeight],@"margin":[NSNumber numberWithFloat:20]};
NSDictionary*viewsArray = @{@"titleView":self.navigationItem.titleView};

[self.navigationItem.titleView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-(>margin=)-H:[titleView(width)]-(>margin=)-|" options:NSLayoutFormatAlignAllCenterX metrics:metricsArray views:viewsArray]];
[self.navigationItem.titleView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[titleView(height)]" options:0 metrics:metricsArray views:viewsArray]];

NSLog(@"%f", self.navigationItem.titleView.width );
*/

したがって、実際に必要なのは

UIImage*image = [UIImage imageNamed:@"logo"];
UIImageView*logoView = [[UIImageView alloc] initWithImage:image];
float targetHeight = self.navigationController.navigationBar.frame.size.height;
[logoView setFrame:CGRectMake(0, 0, 0, targetHeight)];
[logoView setContentMode:UIViewContentModeScaleAspectFit];

self.navigationItem.titleView = logoView;
4
ironik sütlaç

アプリケーションには、ルックアンドフィールのためにUIのカスタマイズされたナビゲーションバーを必要とするビューがいくつかありますが、Navigation Controllerはありません。また、アプリケーションはiOS 11より前のiOSバージョンをサポートする必要があるため、便利なセーフエリアレイアウトガイドを使用できず、ナビゲーションバーの位置と高さをプログラムで調整する必要があります。

上記のようにセーフエリアレイアウトガイドをスキップして、ナビゲーションバーをそのスーパービューに直接添付しました。また、ステータスバーの高さはUIApplicationから簡単に取得できますが、デフォルトのナビゲーションバーの高さは本当に面倒です...

何度か検索とテストを繰り返して、私はほぼ半夜、私が最終的に別の投稿からヒントを得るまで(私には働きませんでした)、UIView.sizeThatFits()から実際に高さを取得できると思いました:

- (void)viewWillLayoutSubviews {
    self.topBarHeightConstraint.constant = [UIApplication sharedApplication].statusBarFrame.size.height;
    self.navBarHeightConstraint.constant = [self.navigationBar sizeThatFits:CGSizeZero].height;

    [super viewWillLayoutSubviews];    
}

最後に、組み込みのものとまったく同じように見える完璧なナビゲーションバー!

2
Stephen Liu

更新に対する私の応答の始まりは次のとおりです。

UIWebViewのコンテンツの高さが回転しても変わらないのはなぜですか?.

自動サイズ変更にはすべての方向の自動サイズ変更マスクがないためでしょうか?

これに戻る前の別の提案として、ニーズに合わせてツールバーを使用できますか。それは少し単純で、常に下部にあり、自動回転/位置になります。好きなように非表示/表示できます。このような種類: http://cdn.artoftheiphone.com/wp-content/uploads/2009/01/yellow-pages-iphone-app-2.jpg

あなたはそのオプションを見たかもしれませんが、ただそこに放り投げます。

別のアイデアとして、回転の方向を検出し、プログラムでボタンを配置してタブバーを調整することもできます。 (これはコードで可能です)

1
Sum

利用した:

let originY: CGFloat = self.navigationController!.navigationBar.frame.maxY

ナビゲーションバーの高さとそのY原点を取得する場合に最適です。

0
user3332228

Handy Swift 4拡張機能(他の人に役立つ場合)。

import UIKit

extension UINavigationController {
  static public func navBarHeight() -> CGFloat {
    let nVc = UINavigationController(rootViewController: UIViewController(nibName: nil, bundle: nil))
    let navBarHeight = nVc.navigationBar.frame.size.height
    return navBarHeight
  }
}

使用法:

UINavigationController.navBarHeight()
0
CodenameDuchess