Можно ли создать iOS-приложение используя только CALayer без UIView?

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

Ответ

Технически возможно, но крайне непрактично. CALayer — это низкоуровневый объект отрисовки без обработки событий и управления жизненным циклом.

Ограничения использования только CALayer:

  • Нет обработки событий — слои не обрабатывают тапы, свайпы, жесты
  • Нет автоматического управления памятью — нужно вручную контролировать retain cycles
  • Нет готовых UI-компонентов — кнопки, текстовые поля, таблицы отсутствуют
  • Сложная анимация — отсутствуют удобные методы анимации UIView

Базовый пример создания слоя:

class LayerOnlyViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()

        // Создание и настройка слоя
        let customLayer = CALayer()
        customLayer.frame = CGRect(x: 50, y: 100, width: 200, height: 150)
        customLayer.backgroundColor = UIColor.systemBlue.cgColor
        customLayer.cornerRadius = 12
        customLayer.borderWidth = 2
        customLayer.borderColor = UIColor.white.cgColor

        // Добавление на экран
        view.layer.addSublayer(customLayer)

        // Проблема: нет обработки тапов на этот слой
        // Решение: добавляем gesture recognizer на view
        let tapRecognizer = UITapGestureRecognizer(target: self, 
                                                   action: #selector(handleTap))
        view.addGestureRecognizer(tapRecognizer)
    }

    @objc func handleTap(_ recognizer: UITapGestureRecognizer) {
        let point = recognizer.location(in: view)
        // Вручную проверяем hit test для каждого слоя
        if let hitLayer = view.layer.hitTest(point) {
            print("Tapped layer: (hitLayer)")
        }
    }
}

Практическая рекомендация: Используйте UIView как контейнер для CALayer. UIView предоставляет:

  • Автоматическое создание и управление backing layer
  • Систему responder chain для обработки событий
  • Удобные методы анимации (UIView.animate)
  • Автоматическое обновление layout при изменении bounds

Гибридный подход (рекомендуется):

class CustomView: UIView {
    override class var layerClass: AnyClass {
        return CAShapeLayer.self // Кастомный тип слоя
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        // Настройка кастомного слоя
        if let shapeLayer = layer as? CAShapeLayer {
            shapeLayer.path = UIBezierPath(roundedRect: bounds, 
                                          cornerRadius: 10).cgPath
        }
    }
}