Программно получить высоту навигационной панели

Я знаю, что наличие большего контроллера просмотра (панель навигации) толкает UIView на его высоту. Я также знаю, что эта высота = 44px. Я также обнаружил, что это нажатие поддерживает [self.view].frame.origin.y = 0.

Итак, как определить высоту этой панели навигации, кроме как просто установить ее на константу?

Или, более короткая версия, как определить, что мой UIView отображается с помощью панели навигации сверху?


Зажгла лампочка. К сожалению, я не нашел единого способа исправить проблему, как описано ниже.

Я считаю, что вся моя проблема связана с моими авторезистентными масками. И причина, по которой я пришел к выводу, что существуют те же симптомы, с UIWebView или без него. И этот симптом заключается в том, что для Портрет характерен все персиковый характер. Для Пейзажа самая нижняя UIButton появляется за TabBar.

Например, на одном UIView у меня сверху вниз:

UIView - оба набора пружин (случай по умолчанию) и отсутствие распорок

UIScrollView. Если я установил две пружины и очистил все остальное (например, UIView), тогда UIButton вторгнется на объект сразу над ним. Если я очистил все, тогда UIButton в порядке, но материал на самом верху скрывается за StatusBar. Установка только верхней стойки, UIButton выскочит за панель вкладок.

UILabel и UIImage, следующий по вертикали - верхняя распорка, гибкая везде

Просто для завершения изображения для тех, у кого есть UIWebView:

UIWebView - Struts: верхняя, левая и правая пружины: обе

UIButton - ничего не задано, т.е. гибко всюду

Хотя моя лампочка тускловата, кажется, есть надежда.


Пожалуйста, несите меня, потому что мне нужно больше места, чем для короткого ответа.

Спасибо, что пытались понять, что я на самом деле ловит рыбу... так вот.

1) Каждый UIViewController (приложение TabBar) имеет UIImage, некоторый текст и все, что сверху. Другим общим знаменателем является UIButton внизу. На некоторых UIViewControllers у меня есть UIWebView над UIButton.

Итак, UIImage, текст и т.д. UIWebView (на некотором) UIButton

В окружении всего перечисленного находится UIScrollView.

2) Для тех, у кого есть UIWebView, его autoresizingMask выглядит так:

   —
   |
   —

   ^
   |
   |

| - | ← ---- → | - |      |      |      В Маска UIButton не имеет ничего заданного, т.е. Гибкого везде

В моем -viewDidLoad я вызываю свой -repositionSubViews, в котором я делаю следующее:

Если нет UIWebView, я ничего не делаю, кроме центра UIButton, который я разместил с IB.

Если у меня есть UIWebView, я определяю его * content * Height и устанавливаю его фрейм, чтобы заключить в него весь контент.

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

Как только я это сделаю, я программным образом выталкиваю UIButton так, чтобы он оказался ниже UIWebView.

Все работает, пока я не поверну его из "Портрет" в "Пейзаж".

Я вызываю my -repositionSubViews в моей -didRotateFromInterfaceOrientation.

Почему высота содержимого моего UIWebView не изменяется с вращением?.

От "Портрет" до "Пейзаж" ширина содержимого должна расширяться, а высота содержимого должна уменьшаться. Это визуально, как должно, но не согласно моему NSLog.

Во всяком случае, с или без UIWebView, кнопка, о которой я говорил о шагах ниже TabBar, когда она находится в режиме Landscape, но она не будет прокручиваться, чтобы ее можно было увидеть. Я вижу это за TabBar, когда я прокручиваю "энергично", но затем он "отступает" за TabBar.

В итоге, это последняя причина, по которой я спросил о высоте TabBar и NavigationBar, потому что TabBar сажает себя в нижней части UIView, а NavigationBar толкает UIView вниз.

Теперь я собираюсь добавить комментарий или два здесь, потому что раньше они не имели смысла.

Без UIWebView я оставляю все так, как это видно IB.

С помощью UIWebView я увеличиваю кадр UIWebView.Hight до его contentHeight, а также настраиваю высоту окружающего UIScrollView, который окружает все под-представления.

Хорошо, что у вас есть.

Ответ 1

Зажгла лампочка. К сожалению, я не нашел единого способа исправить проблему, как описано ниже.

Я считаю, что вся моя проблема связана с моими авторезистентными масками. И причина, по которой я пришел к выводу, что существуют те же симптомы, с UIWebView или без него. И этот симптом заключается в том, что для Портрет характерен все персиковый характер. Для Пейзажа самая нижняя UIButton появляется за TabBar.

Например, на одном UIView у меня сверху вниз:

UIView - оба набора пружин (случай по умолчанию) и отсутствие расположений

UIScrollView - Если я установил две пружины и очистил все остальное (например, UIView), UIButton вторгнется в объект сразу над ним. Если я все уберу, тогда UIButton в порядке, но материал на самом верху скрывается за StatusBar Установив только верхнюю стойку, UIButton выскочит за панель вкладок.

UILabel и UIImage следующая вертикально - верхняя распорка, гибкая везде

Просто для завершения изображения для тех, у кого есть UIWebView:

UIWebView - Struts: верхняя, левая, правая Пружины: оба

UIButton - ничего не установлено, т.е. гибко повсюду

Хотя моя лампочка тускловата, кажется, есть надежда.

Ответ 2

Делать что-то подобное?

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

Быстрая версия находится здесь


UPDATE

iOS 13

Поскольку statusBarFrame устарел в iOS13, вы можете использовать это:

extension UIViewController {

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

    var topbarHeight: CGFloat {
        return (view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0.0) +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
    }
}

Ответ 3

В iPhone-X высота верхней панели (панель навигации + строка состояния) изменяется (увеличивается).

Попробуйте это, если вы хотите точную высоту верхней панели (обе панели навигации + строка состояния):

UPDATE

iOS 13

Поскольку statusBarFrame устарел в iOS13, вы можете использовать это:

extension UIViewController {

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

    var topbarHeight: CGFloat {
        return (view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0.0) +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
    }
}

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 3

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

Ответ 4

версия Swift:

let navigationBarHeight: CGFloat = self.navigationController!.navigationBar.frame.height

Ответ 5

Вы пробовали это?

let barHeight = self.navigationController?.navigationBar.frame.height ?? 0

Ответ 6

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;

Ответ 7

У моего приложения есть пара представлений, для отображения которых требовалась настраиваемая панель навигации в пользовательском интерфейсе, однако без контроллера навигации. И приложение должно поддерживать версию iOS до iOS 11, поэтому удобное руководство по разметке безопасной области не могло быть использовано, и мне пришлось программно регулировать положение и высоту навигационной панели.

Я прикрепил панель навигации к ее суперпредставлению напрямую, пропустив руководство по компоновке безопасной области, как упомянуто выше. И высоту строки состояния можно легко получить из UIApplication, но высота панели навигации по умолчанию действительно мучительная...

Я почти пол ночи провел с поиском и тестированием, пока я, наконец, не получил подсказку из другого поста (хотя и не работал для меня), что вы можете получить высоту из UIView.sizeThatFits(), вот так:

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

    [super viewWillLayoutSubviews];    
}

Наконец, идеальная панель навигации выглядит точно так же, как встроенная!

Ответ 8

Вот начало моего ответа на ваше обновление:

Почему высота содержимого моего UIWebView не изменяется с вращением?.

Может ли быть так, потому что у вашего автоматического изменения размера нет авторезистации для всех направлений?

Еще одно предложение, прежде чем я вернусь за это, вы могли бы использовать панель инструментов для своих нужд. Это немного проще, всегда будет на дне, автоматически вращается/позиционируется. Вы можете скрыть/показать его по желанию и т.д. Пример такого: http://cdn.artoftheiphone.com/wp-content/uploads/2009/01/yellow-pages-iphone-app-2.jpg

Возможно, вы рассмотрели этот вариант, но просто выбросили его.

Еще одна идея: вы могли бы определить, с какой ориентации вы вращаетесь, и просто поместите кнопку программно, чтобы настроить панель вкладок. (Это возможно с кодом)

Ответ 9

Я использовал:

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

Отлично работает, если вы хотите получить высоту панели навигации и ее Y-начало.

Ответ 10

Расширение 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()