iOS7 StatusBarHidden повреждает ScrollView, когда приложение возвращается на передний план

Мое приложение имеет раздел "Камера", который представляет собой модально представленный UINavigationController, содержащий CameraView на основе AVFoundation в качестве его rootViewController. Пользователь может просматривать свои библиотеки фотографий следующим образом: Выдвигается ViewController (->Master), который показывает все группы активов в TableView. Когда пользователь выбирает группу, другой ViewController выдвигается, показывая все активы в этой группе в CollectionView. Ради экранного пространства и "стиля" я решил скрыть строку состояния, когда отображается CameraSection (используя setStatusBarHidden:withAnimation:) Это оставляет NavigationController с панелью навигации, уменьшенной на 20 пикселей (высота StatusBar).

Когда я показываю TableView / CollectionView для просмотра активов, я учитываю это и устанавливаю conentInset и т. Д. Для них соответственно.

Все это работает хорошо и хорошо, пока приложение не будет отправлено в фоновый режим (кнопка "Домой"), показывая либо TableView, либо CollectionView. (сейчас назовем его "ScrollView")

Когда приложение снова выходит на передний план, "ScrollView" находится в нужном состоянии в течение очень короткого момента, пока его кадр не сместится на 44 пикселя вниз. (44px = фактический размер простой навигационной панели - без строки состояния).

Вот несколько картинок, иллюстрирующих проблему:

Перед входом в фон (кнопка "Домой"):Перед входом в фон

После повторного выхода на передний план:

Когда вы присмотритесь, вы можете увидеть темную линию волос у нижнего края панели навигации. На первом рисунке все выровнено как раз правильно. Во втором, однако, scrollView, кажется, имеет смещение кадра вниз на 44px.

Когда contentSize collectionView больше, чем "Screen-Height" (начинает прокручиваться), вы также можете увидеть, что нижний край слишком низок (например, последняя строка не полностью видна + вставка scrollIndicator также неверна).

Я уже пытался зарегистрироваться на уведомления, как UIApplicationDidBecomeActiveNotification или же UIApplicationDidChangeStatusBarFrameNotification и переустановка contentInset и фрейма collectionView в обратном вызове. Key-Value, наблюдающий фрейм collectionView, никогда не вызывал, так же как KVO "topLayoutGuide" viewController.

Похоже, что рамка тихо меняется без каких-либо уведомлений или событий. Как ни странно, когда я NSLog frame и contentInset collectionView до и после повторного ввода, они показывают одинаковые значения!

Я вообще не использую InterfaceBuilder, поэтому все делается в коде (без AutoLayout).

Я был бы очень признателен за любую помощь по этой проблеме.

На данный момент, боюсь, мне придется довольствоваться написанием пользовательского навигационного бара и скрытием навигационного контроллера, чтобы исправить это:/

  • Еще одна проблема, которую я заметил: когда вы скрываете строку состояния, механизм scrollToTop scrollView больше не работает. Я полагаю, что нажатие должно быть в строке состояния, чтобы начать прокрутку, так что, чтобы заставить это работать, скрывая строку состояния, будет необходим TapGestureRecog?

РЕДАКТИРОВАТЬ

К вашему сведению, каждый ViewController, который я использую, наследует от базового класса, который устанавливает automagicallyAdjustScrollViewInset в NO.

1 ответ

Решение

РЕДАКТИРОВАТЬ

На самом деле, решение ниже также не правильно.

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

После сохранения постоянного значения этого свойства все работает нормально.

СТАРЫЙ ОТВЕТ - НЕ РАБОТАЕТ!!

Хорошо, это ОЧЕНЬ ОЧЕНЬ некрасиво, но я смог преодолеть эту проблему, сделав это:

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

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(applicationDidBecomeActive:)
                                             name:UIApplicationDidBecomeActiveNotification
                                           object:nil];

Обратный вызов выглядит так:

- (void)applicationDidBecomeActive:(NSNotification *)notification
{
    UIEdgeInsets scrollIndicatorInset = self.collectionView.scrollIndicatorInsets;
    UIEdgeInsets contentInset = self.collectionView.contentInset;

    scrollIndicatorInset.top -= 44.0;
    scrollIndicatorInset.bottom += 44.0;

    contentInset.top -= 44.0;
    contentInset.bottom += 44.0;

    [self.collectionView setScrollIndicatorInsets:scrollIndicatorInset];
    [self.collectionView setContentInset:contentInset];

    [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidBecomeActiveNotification object:nil];
}

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

Конечно, не хорошее решение, но решение это:/

Другие вопросы по тегам