IOS7 UIScrollView отображает содержимое смещения ниже строки состояния

Я разрабатываю свое приложение для работы с iOS7. У меня есть UINavigationController Я толкаю UIViewController, который имеет ScrollView внутри. Внутри scrollView у меня есть tableView. Возможно ли добиться этого, когда я прокручиваю tableView внутри scrollView, список появится за этой строкой состояния. То же самое было бы, если бы у меня был UINavigationController и UIViewController с табличным представлением в нем.

Так что это иерархия:

UINavigationControllerUIViewControllerUIScrollViewUITableView.

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

Если нет UIScrollView это происходит автоматически в iOS7.

Благодарю.

Ответ 1

Просто установите automaticallyAdjustsScrollViewInsets в NO в методе initController init.

В Storyboard вы можете переключить свойство непосредственно на панели свойств, когда выбран UIViewController.

Если вы используете xib, просто установите его так:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self.automaticallyAdjustsScrollViewInsets = NO;
}

Примечание: это правильно с iOS7 и все еще в iOS8.

Ответ 2

ни один из вышеперечисленных действий для меня, пока я не заметил, что мне пришлось установить Content Insets из Automatically to Never в интерфейсе:

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

Ответ 3

Начиная с iOS 11 вы можете использовать это новое свойство с резервным (Swift 4):

if #available(iOS 11.0, *) {
    scrollView.contentInsetAdjustmentBehavior = .never
}
else
{
    self.automaticallyAdjustsScrollViewInsets = false
}

Ответ 4

Это просто глупо от Apple. Еще одно странное поведение, о котором нужно беспокоиться. Во всяком случае, я закончил настройку прокрутки вставки содержимого для верхнего уровня -20 (от IB).

Ответ 5

Я нашел решение! Просто установите:

self.automaticallyAdjustsScrollViewInsets = false

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

Ответ 6

Вероятно, вы видели эту рекомендацию тысячу раз, но проверьте раздел "Строка состояния" в руководстве по переходу iOS 7 (не можете публиковать прямую ссылку здесь).

Блант возобновления, на ios7 строка состояния является частью представления. Это означает, что почти все, что вы наделите своим взглядом, будет находиться под стойкой, если вы не скажете об обратном. Работа, которую я нашел для этой проблемы, делала непрозрачную строку состояния.

Другим способом может быть отключение строки состояния на этом конкретном представлении. Как в этой теме.

Ответ 7

У меня была аналогичная проблема, и я обнаружил, что для обеспечения того, чтобы содержимое scrollview не попадало под строку состояния, я применил setContentInset.

Итак, в вашей ситуации, если вы используете вставку, я бы предложил использовать UIScrollViewDelegate или scrollViewDidScroll с учетом вашего вида таблицы. Если прокрутка происходит, игнорируйте вставку scrollview.

Ответ 8

не скрывайте панель состояния, scrollView не будет прыгать

Ответ 9

Ответ от Skoua может работать в некоторых ситуациях, но имеет определенные побочные эффекты на iOS11 и более поздних версиях. В частности, представление прокрутки начнет распространять безопасные области своим дочерним элементам, что может испортить ваш макет при прокрутке, если вы используете безопасные области или поля макета.

Apple очень хорошо и подробно объясняет это в этом сеансе WWDC, а также прямо упоминает, что contentInsetAdjustmentBehavior =.never может иметь побочные эффекты и не является тем, что вы должны использовать в большинстве случаев.


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

private var scrollViewSafeAreaObserver: NSKeyValueObservation!

override func viewDidLoad() {

    ...

    if #available(iOS 11.0, *) {
        self.scrollViewSafeAreaObserver = self.scrollView.observe(\.safeAreaInsets) { [weak self] (_, _) in
            self?.scrollViewSafeAreaInsetsDidChange()
        }
    } else {
        self.automaticallyAdjustsScrollViewInsets = false
    }
}

@available(iOS 11.0, *)
func scrollViewSafeAreaInsetsDidChange() {
    self.scrollView.contentInset.top = -self.scrollView.safeAreaInsets.top
}

deinit {
    self.scrollViewSafeAreaObserver?.invalidate()
    self.scrollViewSafeAreaObserver = nil
}

Почему это работает? Потому что мы оставляем contentInsetAdjustmentBehavior =.automatic. Это даст нам нормальное поведение, когда речь идет о оси прокрутки и отсутствия прокрутки, но UIScrollView также "преобразует" любые безопасные области во вставки содержимого. Так как мы не хотим этого для нашего верхнего края, мы просто устанавливаем отрицательную верхнюю безопасную область как наши пользовательские вставки, которые будут противостоять любым вставкам, установленным представлением прокрутки.