Ответ
Кастомная отрисовка в 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), так как они оптимизированы аппаратным ускорением.
Ответ 18+ 🔞
Смотри, ну вот объясняю, как нарисовать свою хрень в 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(_:)руками, как дурак! Система сама его вызовет, когда надо. А чтобы ей намекнуть, что пора, используй:myCustomView.setNeedsDisplay() // Эй, система, перерисуй всю вьюху, нахуй! myCustomView.setNeedsDisplay(rect) // Перерисуй только вот этот кусок, оптимизация же! - Графический контекст — он как одноразовый шприц. Только внутри
draw(_:)он живёт. Не пытайся его вытащить и сохранить в свойство, чтобы потом дорисовать — нихуя не выйдет, получишьnilи депрессию. - Про производительность: Не перерисовывай всё подряд, если можно только кусочек (
rect). Если рисуешь какую-то ебанутую сложную векторную графику, которая не меняется каждую секунду, может, лучше наCAShapeLayerпосмотреть? Оно железом ускоряется. - Для всего, что дрыгается и мигает: Забей на
draw(_:)в лоб. Для анимаций и динамикиCALayer(и его дети вродеCAShapeLayer) — это твои лучшие друзья. Они через GPU работают, а не через CPU, поэтому всё будет гладко, как жопа младенца.