Какие основные причины могут блокировать скролл (прокрутку) в iOS-приложении?

«Какие основные причины могут блокировать скролл (прокрутку) в iOS-приложении?» — вопрос из категории UIKit, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Остановка скролла обычно вызвана проблемами с UIScrollView (или его подклассами UITableView, UICollectionView). Основные причины:

1. Неправильная конфигурация UIScrollView

  • isScrollEnabled = false — свойство явно отключает скролл.
  • Некорректный contentSize — если размер контента меньше или равен размеру bounds скролла, скроллить нечего.
    // Контент должен быть больше видимой области
    scrollView.contentSize = CGSize(width: view.bounds.width, height: 2000)
  • Конфликтующие contentInset или safeAreaInsets — могут "съедать" доступное пространство.

2. Конфликты жестов (Gesture Recognizers)

Другой UIGestureRecognizer (например, на родительском view) может перехватывать или блокировать касания. Решение: Настроить зависимости.

// Заставить жестовый распознаватель панорамирования ждать провала другого жеста
panGestureRecognizer.require(toFail: otherGestureRecognizer)

3. Блокировка основного потока

Длительная синхронная операция на главном потоке (например, цикл, синхронный сетевой запрос) "замораживает" весь интерфейс, включая скролл.

4. Проблемы с иерархией представлений

  • Модальные контроллеры в стиле .pageSheet могут перехватывать жесты.
  • isUserInteractionEnabled = false на самом UIScrollView или его родителях.
  • View поверх скролла может перехватывать касания (hitTest).

5. Специфичные для WKWebView проблемы

// Проверьте, не отключён ли скролл внутри WebView
webView.scrollView.isScrollEnabled = true

Общая диагностика:

  1. Убедитесь, что isScrollEnabled == true.
  2. Проверьте contentSize > bounds.size.
  3. Ищите блокировки главного потока в Instruments (Time Profiler).
  4. Проверьте иерархию жестов с Debug View Hierarchy.