Как в UIKit определить, что UIView находится на экране, без ручных расчетов видимости?

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

Ответ

Да, можно, но с оговорками. Прямого свойства isVisible в UIKit нет. Основные подходы:

1. Проверка через window и иерархию:

// View считается "на экране", если у нее есть window и она находится в иерархии ключевого окна.
let isOnScreen = view.window != nil && view.isDescendant(of: view.window!)

⚠️ Ограничение: Этот метод не учитывает, перекрыта ли view другими элементами, скрыта ли (isHidden = true) или имеет нулевую альфа-прозрачность.

2. Использование жизненного цикла UIViewController (наиболее надежно): Отслеживайте состояние в методах viewDidAppear(_:) и viewDidDisappear(_:) соответствующего контроллера.

3. Для ячеек таблицы или коллекции:

// Для UITableViewCell
if let tableView = superview as? UITableView,
   let indexPath = tableView.indexPath(for: self),
   tableView.indexPathsForVisibleRows?.contains(indexPath) == true {
    // Ячейка видима
}

Вывод: Универсального и идеального способа нет. Для контроллеров используйте жизненный цикл. Для произвольных view комбинируйте проверку window и isDescendant(of:), понимая ограничения.