Где реализуется кастомная логика отрисовки UIView в UIKit?

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

Ответ

Кастомная отрисовка в UIView выполняется путем переопределения метода draw(_ rect: CGRect). Этот метод предоставляет графический контекст (CGContext) для рисования с помощью Core Graphics.

Базовый пример:

class CustomView: UIView {
    override func draw(_ rect: CGRect) {
        // 1. Получаем текущий графический контекст
        guard let context = UIGraphicsGetCurrentContext() else { return }

        // 2. Настраиваем параметры рисования
        context.setFillColor(UIColor.systemBlue.cgColor)
        context.setStrokeColor(UIColor.black.cgColor)
        context.setLineWidth(2.0)

        // 3. Определяем прямоугольник для рисования
        let drawingRect = CGRect(x: 20, y: 20, width: 100, height: 100)

        // 4. Рисуем и заливаем прямоугольник
        context.addRect(drawingRect)
        context.drawPath(using: .fillStroke)
    }
}

Ключевые принципы:

  • Не вызывайте draw(_:) напрямую. Чтобы система вызвала этот метод, необходимо пометить view как требующее перерисовки:
    myCustomView.setNeedsDisplay() // Перерисовать всю view
    myCustomView.setNeedsDisplay(rect) // Перерисовать только указанную область
  • Графический контекст доступен только внутри draw(_:). Не пытайтесь сохранить UIGraphicsGetCurrentContext() для использования позже.
  • Для производительности: Ограничивайте область перерисовки (rect), используйте setNeedsDisplay(in:). Для сложной векторной графики рассмотрите использование CAShapeLayer.
  • Альтернатива для анимаций: Для анимированных или часто меняющихся элементов более эффективно использовать CALayer и его подклассы (например, CAShapeLayer), так как они оптимизированы аппаратным ускорением.