Есть ли способ изменить высоту 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 по умолчанию, но в инспекторе должен быть вариант)
(Я также вижу, что люди отвечают на программные способы решения этого вопроса. Несмотря на то, что эти ответы работают, мне все равно придется разрабатывать раскадровку с учетом этого (пробел). Я хочу знать, если это возможно установить это в раскадровке или, вернее, почему это не разрешено?)
Ответы
Ответ 1
Вы можете установить свойство barPosition
на 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
Ответ 9
В Swift 3 с использованием основной раскадровки вы можете использовать ограничения, чтобы изменить высоту и заставить ее работать. Это было так, как я нашел, легко реализовать.
Создание ограничений.
Как это выглядит в конце.
Ответ 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). Опять же, я знаю, что это супер хаки, но для меня это делается. Вот как это выглядит сейчас
![введите описание изображения здесь]()