UINavigationBar/ Ошибка строки состояния в IOS7

Окончательное редактирование

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

Настройка контроллера

У меня есть приложение, которое настроено следующим образом:

InitialViewController (подкласс https://github.com/edgecase/ECSlidingViewController)

Главный навигационный контроллер (подкласс UINavigationController)

Main Home View Controller (подкласс UIViewController)


в viewDidLoad Из начального ViewController я загружаю основной контроллер навигации с Home View Controller в качестве его корня.

self.topViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"MainNavVC"];

Проблема

При первой загрузке приложения строка состояния и панель навигации разделяются. введите описание изображения здесь

Это желаемый эффект.

Однако затем я загружаю контроллер модального представления и закрываю его, используя стандартные методы:

[self performSegueWithIdentifier:@"LoadSelectOpponentVC" sender:self];

Затем закройте с помощью:

[self dismissViewControllerAnimated:YES completion:nil];

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

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

тестирование

  1. Для параметра plist установлено значение YES - View controller-based status bar appearance
  2. Я пытался установить edgesForExtendedLayout для соответствующих нет, но без изменений.

логирование

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

При первой загрузке:

Main Nav VC - Просмотр кадра - {{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

15 ответов

Пробовали ли вы рекомендацию Apple о том, что "не допускать, чтобы строка состояния скрывала ваши взгляды": https://developer.apple.com/library/content/qa/qa1797/_index.html

А вы взглянули на "UIBarPositionDelegate": https://developer.apple.com/documentation/uikit/uibarpositioningdelegate

В iOS 7.0 UIViewController по умолчанию работает таким образом. Вид будет полноэкранным, если вы используете UIViewController внутри UINavigationController и navigationBar виден

Если навигационная панель видна, сделайте следующее. ==>

self.edgesForExtendedLayout = UIRectEdgeNone

если навигационная панель скрыта, выполните следующие действия. ==>

Отрегулируйте все UIView элементы, сдвигая 20 очков

Если вы используете Interface Builder, вы можете использовать iOS6/7 delta: сначала "view as iOS 6.0", затем установите "20" для достижения смещения +20 в iOS 7.

Я удивлен, что никто не нашел правильный ответ. UIBarPositionDelegate работает как шарм! Просто сделайте ваш контроллер вида UIBarPositionDelegate и назначьте его в качестве делегата панели. Расположите панель в 20 пикселях от верхней части вашего обзора. Затем добавьте этот метод в свой контроллер представления (доступно только в iOS7+):

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

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

[self.navigationController setNavigationBarHidden:YES/NO animated:NO];

в контроллере вида меню.

Я исправил такую ​​проблему, используя ответ из этого поста: iOS 7 | Кнопки панели навигации / панели инструментов расположены очень близко к строке состояния

Используя Autolayout, вы должны игнорировать установку нового кадра. Вы должны добавить ограничение Top Space, равное 20, для TopBar для iOS 7.

Вы пытались добавить следующий код к вашему viewDidLoad метод:

if ([self respondsToSelector:@selector(edgesForExtendedLayout)])
    self.edgesForExtendedLayout = UIRectEdgeNone;

Это быстро объясняется переходом Apple на iOS 7 .

Я знаю, что у вас есть ViewController в качестве основного VC. Но если кто-то использует UITableviewController и имеет ту же проблему, этот код решает проблему:

self.tableView.contentInset = UIEdgeInsetsMake(20.0f, 0.0f, 0.0f, 0.0f);

Я подробно ответил на эту проблему в этом ответе на аналогичный вопрос. Короткий ответ таков: нет способа получить автоматическое поведение макета строки состояния, к которому вы привыкли в iOS 6 и более ранних версиях. Вам придется придумать дизайн или найти способ имитировать старый стиль (я рассматриваю оба подхода).

Я настоятельно советую вам не вносить ручные изменения в рамку панели навигации. Пусть UINavigationController справится с этим самостоятельно. Скорее всего, ваша проблема в том, что кадр представления вашего контроллера навигации не равен границам UIScreen.

Решение этого на самом деле очень просто. Это включает в себя манипулирование UINavigationBar's 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

Да была такая же проблема. выполнил весь шаг, но без изменений.

Чтобы все заработало, убедитесь, что AutoLayout настроен правильно для всего экрана, а не только для вида сверху / панели инструментов, как указано в

"Предотвращение того, чтобы строка состояния скрывала ваши взгляды": https://developer.apple.com/library/ios/qa/qa1797/_index.html

По крайней мере, для всех видов чуть ниже основного Viewcontroller.view.

Для меня решением было сдвинуть панель навигации к 20 пунктам введите описание изображения здесь

Есть встроенный способ сделать это. То же, что и ответ Джоэла Кейва, но уточняется:

Сделайте так, чтобы у вашей навигационной панели было начало координат в 20 точек.

Тогда в.h файле:

@interface XYZViewController : UIViewController <UIBarPositioningDelegate>

И в файле.m:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.navigationBar.delegate = self;
}

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

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

Я исправил проблему, реализовав

- (BOOL)shouldAutorotate
{
    return NO;
}

в контроллере представления, который представляет модал.

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

[self.navigationController.navigationBar setTranslucent:NO];

Если вы создали свой вид с раскадровкой, то вы можете решить эту проблему с помощью XCode. Выберите виджет NavigationBar и снимите флажок "Полупрозрачный".

Лучший способ - добавить это, если у вас есть проблема с:

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);
Другие вопросы по тегам