Добавление UINavigationController в качестве подпредставления UIView

Я пытаюсь отобразить UILabel поверх UINavigationController. Проблема в том, что когда я добавляю UILabel в качестве подпредставления UIWindow, он не будет автоматически вращаться, поскольку он не является подвидом UIViewController (UIViewController автоматически обрабатывает обновление подпредставлений во время вращения).

Это иерархия, которую я использовал:

  • UIWindow
    • UILabel
    • UINavigationController

Итак, я подумал, что могу использовать следующую иерархию:

  • UIWindow
    • UIViewController
      • UIView
        • UILabel
        • UINavigationController

Таким образом, метка может отображаться поверх панели UINavigationController, а также автоматически поворачиваться, поскольку она является подвидом UIViewController.

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

[myViewController.view addSubview:myNavigationController.view];

он появится на 20 пикселей вниз. Я предполагаю, что это потому, что он думает, что ему нужно освободить место для строки состояния. Но поскольку UINavigationController размещается внутри UIView, который не накладывается поверх строки состояния, он неправильно добавляет дополнительные 20 пикселей. Другими словами, верхняя часть UINavigationBar находится на отметке экрана 40 пикселей вместо 20 пикселей.

Есть ли простой способ просто переместить UINavigationController и все его элементы (например, панель навигации, панель инструментов, контроллер корневого представления) на 20 пикселей? Или дать ему понять, что он не должен компенсировать строку состояния?

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

Примечание. Под «отображением метки поверх панели навигации» я подразумеваю, что она должна накладываться поверх панели навигации ... ее нельзя просто обернуть в элемент кнопки панели и поместить как один из элементов Панель навигации.


person Senseful    schedule 26.03.2010    source источник


Ответы (5)


Использование этого кода, похоже, работает:

nav.view.frame = CGRectMake(nav.view.frame.origin.x, nav.view.frame.origin.y - 20,
                          nav.view.frame.size.width, nav.view.frame.size.height);

Я сделал это перед добавлением контроллера навигации в качестве подпредставления. Использование [UIApplication sharedApplication] .statusBarFrame вместо жестко запрограммированных 20, вероятно, тоже будет хорошей идеей.

Я не уверен, что это лучший способ сделать это.

person Senseful    schedule 26.03.2010
comment
используйте nav.view.frame = CGRectMake (0,0, self.view.frame.size.width, self.view.frame.size.height); чтобы это также работало на ipad, у которого нет ошибки +20, но вместо этого есть другие проблемы с шириной и высотой, в целом это полная черепица, очень неаккуратная, как яблоко - person valexa; 19.08.2010
comment
У меня есть пример, когда, если я загружаю представление UINavigationController как подпредставление в альбомном режиме на iPad, я получаю ошибку 20 пикселей. Но только в первый раз. Я могу повторно добавить в супервизор позже, и проблема исчезнет. Очень-очень неприятно. - person Daniel Wood; 25.11.2011
comment
Кажется, у меня такая же проблема. На самом деле ничего не говорит мне о том, что панель навигации имеет смещение по вертикали на 20 пикселей. @DanielWood Я действительно разделяю ваше разочарование. Если я нажимаю, а затем нажимаю другой контроллер, все в порядке, но в первый раз ... Я попробую поиграть. - person Vaseltior; 24.03.2012
comment
Я думаю, что предложение Я сделал это перед добавлением контроллера навигации в качестве подпредставления. должно быть написано жирным, красным, подчеркнутым шрифтом - для меня это была самая важная часть решения 20-пиксельной проблема. Когда я устанавливаю фрейм представления навигации перед добавлением его в качестве подпредставления - проблема исчезла :) - person Neo; 11.04.2012
comment
Это должно устранить проблему для нескольких перезагрузок navigaitonView в родительском вложенном представлении. gist.github.com/2961401 - person ArtSabintsev; 20.06.2012

Если вы хотите, чтобы фрейм представлял доступную область содержимого, вы должны просто использовать: [[UIScreen mainScreen] applicationFrame]. Конечно, это ограничивает ваш контроллер представления верхнего уровня, так что он может быть только верхним уровнем. Так что все еще немного хитроумно, но в меньшей степени.

person Casebash    schedule 23.09.2010

Почему бы вам не использовать фрейм приложения вместо добавления некоторых значений к источникам? Я имею в виду использование:

CGRect appFrame = [[UIScreen mainScreen] applicationFrame];

в качестве системы отсчета и сделайте что-то вроде этого:

nav.view.frame = CGRectMake(appFrame.origin.x, appFrame.origin.y, ...

Этот сработал для меня.

person superkeci    schedule 31.10.2011

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

Я заметил, что представление моего контроллера представления имело правильный фрейм, а панель навигации контроллера представления - нет (у него было начало кадра (0,20)).

Вставьте это в контроллер представления, который является супервизором контроллера навигации:

- (void) viewDidAppear:(BOOL)animated {
    if (navigationController.navigationBar.frame.origin.y != 0) {
        [[navigationController view] removeFromSuperview];
        [[self view] addSubview:navigationController.view];
    }
}
person Matt Toohey    schedule 17.04.2012

Swift 5: добавьте следующую строку в viewDidLoad() корневого контроллера представления UINavigationController.

self.edgesForExtendedLayout = [.top, .bottom]
person Li Jin    schedule 24.07.2020