Ошибка UINavigationBar/Status Bar в IOS7
Окончательный EDIT
(Вместо того, чтобы иметь слишком длинный вопрос с изменениями, делающими окончательное редактирование для уточнения, см. другие изменения, если это необходимо).
Настройка контроллера
У меня есть приложение, которое настроено следующим образом:
InitialViewController (подкласс ECSlidingViewController)
Главный навигационный контроллер (подкласс UINavigationController
)
Main Home View Controller (подкласс UIViewController
)
В viewDidLoad
элемента initialViewController я загружаю главный навигационный контроллер с контроллером Home View в качестве его корня.
self.topViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"MainNavVC"];
Проблема
При первой загрузке приложения строка состояния и панель навигации разделены.
![enter image description here]()
Это желаемый эффект.
Однако затем я загружаю контроллер модального представления и закрываю его, используя стандартные методы:
[self performSegueWithIdentifier:@"LoadSelectOpponentVC" sender:self];
Затем закройте:
[self dismissViewControllerAnimated:YES completion:nil];
Это, в свою очередь, приводит к тому, что главный контроллер навигации (удерживая контроллер домашнего вида) неправильно отображает строку состояния и перекрывается:
![enter image description here]()
Тестирование
- Настройка plist установлена на YES -
View controller-based status bar appearance
- Я попытался установить
edgesForExtendedLayout
на соответствующий none, но никаких изменений.
Вход
Я попытался вывести некоторые фреймы, чтобы увидеть, где возникла проблема:
При первой загрузке:
Main Nav VC - View Frame - {{0, 0}, {320, 480}}
Main Nav VC - Nav Bar Frame - {{0, 0}, {320, 44}}
Initial VC - View Frame - {{0, 0}, {320, 480}}
Home VC - View Frame - {{0, 0}, {320, 480}} -- viewDidLoad Home VC
Home VC - View Frame - {{0, 64}, {320, 416}} -- viewWillAppear Home VC
--- After Modal is opened/closed ----
Home VC - View Frame - {{0, 64}, {320, 416}} -- viewWillAppear Home VC
Main Nav VC - View Frame - {{0, 0}, {320, 480}} -- viewWillAppear Main Nav
Main Nav VC - Nav Bar Frame - {{0, 20}, {320, 44}} -- viewWillAppear Main Nav
Home VC - View Frame - {{0, 44}, {320, 436}} -- viewDidAppear Home VC
Ответы
Ответ 1
Вы попробовали рекомендацию Apple по поводу "Предотвращение отображения строки состояния от просмотра ваших просмотров": https://developer.apple.com/library/content/qa/qa1797/_index.html
И вы посмотрели "UIBarPositioningDelegate": https://developer.apple.com/documentation/uikit/uibarpositioningdelegate
Ответ 2
В iOS 7.0 UIViewController
работает по умолчанию таким образом. Просмотреть будет полный экран, если вы используете UIViewController внутри UINavigationController
, и отображается navigationBar
.
Если отображается NavigationBar, выполните следующие действия.
== >
self.edgesForExtendedLayout = UIRectEdgeNone
если navigationBar скрыт, выполните следующие действия.
== >
Отрегулируйте все элементы UIView
, сдвинув 20 пунктов
Если вы используете построитель интерфейса, вы можете использовать дельта iOS6/7: во-первых, "просматривать как iOS 6.0", а затем установить дельта "20", чтобы достичь смещения +20 в iOS 7
Ответ 3
Я удивлен, что никто не ударил по правильному ответу. UIBarPositioningDelegate работает как шарм! Просто сделайте свой контроллер просмотра UIBarPositioningDelegate и назначьте его как делегат панели. Расположите планку на 20 пикселей сверху. Затем добавьте этот метод в свой контроллер просмотра (доступен только в iOS7 +):
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar
{
return UIBarPositionTopAttached;
}
Ответ 4
У меня была аналогичная проблема с кнопкой меню "гамбургер", которая сдвигала главный контроллер представления и имела контроллер меню на стороне. Я обнаружил, что на панели навигации контроллера меню не было известно, отображается ли строка состояния или нет. Я исправил это, разместив уведомление, когда была отображена строка состояния и hiddden, затем выполнив
[self.navigationController setNavigationBarHidden:YES/NO animated:NO];
в диспетчере меню.
Ответ 5
Вы пытались добавить следующий код в свой метод viewDidLoad:
if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
self.edgesForExtendedLayout = UIRectEdgeNone;
В Apple быстро объясняется переход на iOS 7 doumentation: https://developer.apple.com/library/ios/documentation/userexperience/conceptual/TransitionGuide/AppearanceCustomization.html
Ответ 6
Я исправил такую проблему, используя ответ из этого сообщения: iOS 7 | Панель навигации/кнопки панели инструментов очень близко к строке состояния
Используя Autolayout, вы должны игнорировать установку нового фрейма. Вы должны добавить Top Space Constraint равным 20 для TopBar для iOS 7.
Ответ 7
Я ответил на эту проблему длиной в этом ответе на аналогичный вопрос. Короткий ответ таков: нет способа получить автоматическое поведение макета строки состояния, к которому вы привыкли, начиная с iOS 6 и ранее. Вам придется проектировать вокруг него или найти способ имитировать старый стиль (я охватываю оба подхода).
Я настоятельно рекомендую вам не выполнять ручную настройку на рамку навигационной панели. Пусть UINavigationController обрабатывает это самостоятельно. Скорее всего, ваша проблема заключается в том, что ваш ракурс просмотра навигационного контроллера не равен ограничениям UIScreen.
Ответ 8
Я знаю, что у вас есть ViewController в качестве основного VC. Но если кто-то использует UITableviewController и имеет ту же проблему, этот код решает проблему:
self.tableView.contentInset = UIEdgeInsetsMake(20.0f, 0.0f, 0.0f, 0.0f);
Ответ 9
Решение этого на самом деле очень просто. Он включает в себя манипулирование значением UINavigationBar center.y
, которое использует UIKit для настройки UINavigationBar на высоту строки состояния. Для простоты я подклассифицировал UINavigationBar и сделал следующее:
@implementation MyNavigationBar
- (void) setCenter:(CGPoint)center {
// Anything less than or equal to 22 is something we don't want (below SB height)
if(center.y > 22) [super setCenter:center];
}
@end
Ответ 10
Да, такая же проблема. после всех шагов, но без изменений.
Попробовал работать, убедившись, что AutoLayout настроен правильно для всего экрана не только для верхнего вида/панели инструментов, как указано в
"Предотвращение отображения строки состояния из ваших представлений": https://developer.apple.com/library/ios/qa/qa1797/_index.html
По крайней мере для всех представлений чуть ниже основного Viewcontroller.view.
Ответ 11
Существует встроенный способ сделать это.
То же, что и Джоэл Кейв, но уточнил:
Сделайте свою навигационную панель с Y-началом 20 точек.
Затем в файле .h:
@interface XYZViewController : UIViewController <UIBarPositioningDelegate>
И в файле .m:
- (void)viewDidLoad {
[super viewDidLoad];
self.navigationBar.delegate = self;
}
- (UIBarPosition)positionForBar:(id<UIBarPositioning>)bar {
return UIBarPositionTopAttached;
}
Ответ 12
Для меня решение было сдвинуть навигационную панель на 20 пунктов ![ввести описание изображения здесь]()
Ответ 13
Я немного опоздал на вечеринку, но так как я столкнулся с той же проблемой, и это был первый результат, который появился в поиске, я думаю, что мой ответ мог бы помочь другим людям:)
Я исправил проблему, выполнив
- (BOOL)shouldAutorotate
{
return NO;
}
в контроллере представления, который представляет модальный.
Ответ 14
Попробуйте, все навигационные панели должны быть полупрозрачными, отключены.
[self.navigationController.navigationBar setTranslucent:NO];
Если вы разработали свое представление с помощью раскадровки, вы можете решить проблему с помощью XCode. Выберите виджет NavigationBar и снимите флажок "Прозрачный".
![enter image description here]()
Ответ 15
лучший способ - добавить это в представление, в котором у вас есть проблема:
if (self.navigationController.navigationBar.frame.origin.y==0)
self.navigationController.navigationBar.frame =
CGRectMake(self.navigationController.navigationBar.frame.origin.x,
self.navigationController.navigationBar.frame.origin.y,
self.navigationController.navigationBar.frame.size.width,
64);