Подтвердить что ты не робот

Есть ли способ изменить высоту UINavigationBar в Storyboard без использования UINavigationController?

Я хочу использовать пользовательский UINavigationBar в одном из моих представлений, который не является частью любой UINavigationController -иерархии. Когда я перетаскиваю UINavigationBar в Storyboard, он выглядит следующим образом:

UINavigationBar

Эта строка - 44 пикселя, что было бы достаточно, если строка состояния не разделила бы это пространство. Поскольку iOS7 позволяет использовать весь экран, включая пробел для строки состояния, UINavigationBar должен быть 64px, а не 44px.

Если я подключу представление к иерархии UINavigationController, то он будет выглядеть правильно:

UINavigationController

Я где-то читал, что , если UINavigationBar имеет свойство barPosition:, установленное на UIBarPositionTopAttached, тогда панель будет 64px. Это, однако, readonly -property.

Мои результаты поиска показали только то, что я считаю "обходным". Добавляя бесполезный UINavigationController до этого UIViewController, я могу притворяться, что у меня есть иерархия, и он автоматически добавит UINavigationBar с 64px.

Не существует действительно, чтобы иметь "жулик" (без помощи контроллера навигации) UINavigationBar, который охватывает 64px? Если это так, есть ли веские причины, почему?

(Я не говорю, что UINavigationBar должен быть 64px по умолчанию, но в инспекторе должен быть вариант)

(Я также вижу, что люди отвечают на программные способы решения этого вопроса. Несмотря на то, что эти ответы работают, мне все равно придется разрабатывать раскадровку с учетом этого (пробел). Я хочу знать, если это возможно установить это в раскадровке или, вернее, почему это не разрешено?)

4b9b3361

Ответ 1

Вы можете установить свойство barPosition на UIBarPositionTopAttached другим способом!

  • Добавить делегат для вас UINavigationBar.
  • Внедрить -positionForBar: в класс делегата:

    - (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
    {
        return UIBarPositionTopAttached;
    }
    

Верхняя панель навигации также должна быть привязана к руководству Top Layout.

Ответ 2

Программно можно изменить высоту панели навигации:

[navBar setFrame:CGRectMake(0, 0, 320, 64)];

Изменить: как я писал в комментариях, вам, возможно, придется поместить эту строку в viewDidLayoutSubviews, чтобы обойти автоотключение.

Ответ 3

Вы можете установить его для присоединения к верхней части представления с использованием "Определенных пользователем атрибутов времени выполнения" в "Индексе идентификации" в Interface Builder. Задайте свойство barPosition.

enter image description here

Здесь документация для свойства barPosition: https://developer.apple.com/library/ios/documentation/uikit/reference/UIBarPositioning_Protocol/Reference/Reference.html

Ответ 4

Существует способ выполнить это БЕЗ использования UINavigationController или установить его программно. Просто установите ограничение высоты на панели навигации на все, что вам нужно, 64 в этом случае.

Вы можете сделать то же самое программно как таковое:

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:navigationBar attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeHeight multiplier:1 constant:64.0f]];

EDIT:

Как указывала @nerdist-colony, при работе с Autolayout всегда было установлено translatesAutoresizingMaskIntoConstraints - NO, иначе могут быть конфликты в ограничениях.

Ответ 5

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

Я исправил его с помощью ограничений и родительского UIView. Я установил этот UIView в раскадровке как родительское представление моего UINavigationBar с фреймом {0, 0, 320, 64}. Вы можете добавить ограничение или набор ограничений, заставляющих UINavigationBar иметь нужный размер. И учитывая, что ваш родительский UIView имеет правильный фрейм в вашем раскадровке, вы можете как обычно использовать свои другие представления в своем раскадровке.

Теперь, если автоматическое отключение отключено, вы можете изменить высоту бара программно, как описано в ответе Линдси. -(void)viewDidLayoutSubviews кажется хорошим местом для этого.

Ответ 6

Если вы используете Autolayout, вы можете установить ограничение ограничения для UINavigationBar на 64 или событие больше.

Ответ 7

@startupThekid:

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

Тем не менее, эквивалент Swift объектного кода C, который вы выложили:

var navBar = self.navigationController!.navigationBar 

в 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)

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

Ответ 8

Я написал сообщение в блоге, в котором подробно описывается, как это сделать при минимальном вмешательстве кода. Ваш бар покажет пробел в раскадровке, но он отлично работает на устройстве. Короче говоря, шаги:

1) Добавьте панель навигации в контроллер просмотра в раскадровке.

2) Задайте ограничения для панели навигации в раскадровке:
 - Навигационная панель.Топ = Верхний макет Guide.Bottom
 - Панель навигации. Листинг = Superview.Leading
 - Панель навигации. Trail = Superview.Trailing

3) Подключите навигационную панель раскадровки к контроллеру своего вида как @IBOutlet.

4) В классе контроллера вида добавьте в декларацию класса протокол UINavigationBarDelegate.

5) В методе viewDidLoad контроллера view установите делегат панели навигации в self.

6) В контроллере представления добавьте способ позиционирования делегата positionForBar. Верните UIBarPosition, представляющий TopAttached. (Примечание: UINavigationBarDelegate наследует этот метод из UIBarPositioningDelegate.)

Полная запись с изображениями GIF находится здесь:
Легко использовать панель навигации без соответствующего контроллера навигации

Эти шаги работают с Swift 2.1/Xcode 7.2

Ответ 10

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

Я устанавливаю свой контроллер представления как UINavigationBarDelegate и внедряю positionForBar: для возврата UIBarPositionTopAttached, например user3269713 answer. Казалось, что другой трюк состоял в том, чтобы использовать автоматическую компоновку, чтобы расположить планку ниже topLayoutGuide.

Это был код, который я использовал в 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]];

И да, как я и надеялся, это автоматически перемещает панель, когда вы поворачиваетесь к пейзажу, а строка состояния скрывается.

(Сердечно рекомендую помощника автомакета, такого как масонство, которое делает код макета более кратким, а масонство, например, заботится об отключении translatesAutoresizingMaskIntoConstraints для вас)

Ответ 11

Я знаю, что это очень хакерский способ сделать это, но для меня это сработало. У меня есть NavigationViewController, и я хочу загрузить ViewController, который имеет UINavigationBar вверху с кнопками Done и Cancel. Вот как это выглядело: введите описание изображения здесь

Как вы можете видеть, в верхней части есть белая полоса, которую я хочу быть того же цвета, что и UINavigationBar. Вместо того, чтобы изменять высоту UINavigationBar программно, я просто сделал новый вид и установил его цвет фона, равный его цвету UINavigationBar (HEX = F8F8F8, RGBA = 248,248,248,1.0). Опять же, я знаю, что это супер хаки, но для меня это делается. Вот как это выглядит сейчас

введите описание изображения здесь