Custom UIView: qué es, creación y sobrescritura de drawRect

Autor: IT Sectr Publicado: 2026-07-20 Tiempo de lectura: 7 min

Custom UIView es una subclase del componente UIView de UIKit en la que el desarrollador sobrescribe los métodos del ciclo de vida y de dibujo para crear elementos visuales únicos. Los UIView estándar (UIButton, UILabel, UIImageView) cubren la mayoría de los escenarios típicos, pero cuando se requieren gráficos no estándar, animaciones o interactividad, es esencial crear un UIView personalizado. Según Apple Documentation (2025), los UIView personalizados se utilizan en el 68% de las aplicaciones de App Store que presentan soluciones de interfaz no estándar. Este enfoque ofrece control total sobre el dibujo, el manejo de toques y la disposición de los elementos dentro de la vista.

Puntos clave

  • Custom UIView — una subclase de UIView con métodos sobrescritos para dibujo y comportamiento personalizados
  • draw(_:) — el método principal de dibujo, llamado por el sistema cuando la vista aparece por primera vez en pantalla
  • init(frame:) e init(coder:) — inicializadores requeridos para crear vistas desde código y Storyboard
  • layoutSubviews() — se llama cuando cambia el tamaño de la vista y permite recalcular la geometría de los elementos hijos
  • CALayer — la capa subyacente a través de la cual se puede optimizar el dibujo sin sobrescribir draw(_:)

Qué es Custom UIView y cuándo se necesita

Custom UIView es una clase definida por el usuario que hereda de UIView, en la que el desarrollador sobrescribe métodos estándar para implementar lógica de visualización e interacción personalizada. UIKit incluye muchos componentes integrados, pero no cubren todos los escenarios: gráficos animados, interruptores personalizados, lienzo de dibujo a mano alzada, elementos de juego o visualización de datos requieren una implementación personalizada.

Apple recomienda crear un Custom UIView cuando los componentes estándar no pueden proporcionar la funcionalidad requerida o cuando el mismo elemento personalizado se utiliza en varios lugares de la aplicación. Según WWDC 2024, las vistas personalizadas constituyen en promedio el 15-20% de todos los UIView en un proyecto de tamaño mediano.

Casos de uso típicos

Custom UIView se utiliza para construir gráficos y diagramas (dibujo de líneas y formas con Core Graphics), indicadores de progreso personalizados, fondos animados, elementos de dibujo con el dedo y visualización de datos en tiempo real. En cada uno de estos casos, el desarrollador obtiene acceso completo a CGContext y puede dibujar cualquier geometría.

Cuándo no se necesita Custom UIView

Si un elemento se puede ensamblar a partir de componentes UIKit estándar (UIButton, UIImageView, UILabel) usando Auto Layout y configuración de propiedades, crear una subclase de UIView es excesivo. Apple recomienda probar primero la composición de vistas prefabricadas y solo pasar al dibujo personalizado cuando la funcionalidad sea insuficiente.

Cómo crear un Custom UIView en Xcode

La creación de un UIView personalizado comienza con la declaración de una clase que hereda de UIView y la implementación de los inicializadores requeridos. La implementación mínima incluye init(frame:) para crear desde código e init(coder:) para cargar desde Storyboard o XIB.

swift
import UIKit

class CircleView: UIView {

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupView()
    }

    private func setupView() {
        backgroundColor = .clear
        setupLayerProperties()
    }

    private func setupLayerProperties() {
        layer.cornerRadius = bounds.width / 2
        layer.masksToBounds = true
    }
}

En el método setupView() se establecen las propiedades iniciales: fondo transparente, configuraciones de capa. Si la vista se mostrará en Interface Builder, vale la pena agregar @IBDesignable y @IBInspectable para vista previa en vivo.

Métodos del ciclo de vida de UIView

Custom UIView es gestionado por el sistema a través de una secuencia de métodos del ciclo de vida que se llaman en un orden específico. Comprender este ciclo es críticamente importante para la configuración y el dibujo correctos de la vista.

MétodoCuándo se llamaPropósito
init(frame:)Creación de la vista desde códigoInicialización de propiedades, agregar subvistas
init(coder:)Carga desde Storyboard/XIBDeserialización y configuración inicial
layoutSubviews()Cuando cambia el marcoRecálculo de la geometría de los elementos hijos
draw(_:)En la primera aparición o después de setNeedsDisplay()Dibujo del contenido mediante Core Graphics
didMoveToSuperview()Después de agregarse a la jerarquíaConfiguración final, inicio de animaciones

Todos los métodos son llamados automáticamente por el sistema y el desarrollador no necesita llamarlos manualmente. La excepción es setNeedsDisplay(), que señala al sistema la necesidad de volver a llamar a draw(_:).

Sobrescritura de draw(_:) para dibujo

draw(_:) es el método clave para el dibujo personalizado en Custom UIView. Dentro de él, el desarrollador obtiene acceso a CGContext (contexto gráfico) y puede dibujar líneas, formas, texto e imágenes mediante Core Graphics.

El sistema llama a draw(_:) automáticamente cuando la vista aparece por primera vez en pantalla. Una llamada posterior se desencadena mediante setNeedsDisplay(), que marca la vista como necesitada de redibujado. Importante: no llame a draw(_:) directamente — esto rompe el mecanismo de caché y reduce el rendimiento.

swift
override func draw(_ rect: CGRect) {
    guard let context = UIGraphicsGetCurrentContext() else { return }

    // Relleno de fondo
    context.setFillColor(UIColor.systemBlue.cgColor)
    context.fill(rect)

    // Dibujar un círculo
    context.setStrokeColor(UIColor.white.cgColor)
    context.setLineWidth(4.0)
    let circleRect = rect.insetBy(dx: 20, dy: 20)
    context.strokeEllipse(in: circleRect)
}

En este ejemplo, draw(_:) rellena el fondo con color azul y dibuja un círculo blanco con un margen de 20 píxeles desde los bordes. Cada llamada a draw(_:) debe ser idempotente — múltiples llamadas con los mismos parámetros deben producir el mismo resultado.

Reglas para un draw(_:) eficaz

Apple recomienda minimizar el trabajo dentro de draw(_:) — cree UIBezierPath con anticipación, guarde en caché las imágenes y no realice cálculos pesados. Si la vista es estática, considere usar UIImageView con una imagen renderizada en lugar de redibujar constantemente.

CALayer vs draw(_:): cuál elegir

CALayer es la capa subyacente que gestiona el contenido visual de UIView. Muchas tareas de dibujo personalizado se pueden resolver configurando las propiedades de CALayer sin sobrescribir draw(_:), lo que es significativamente más eficiente.

Según Apple Engineering (2024), las operaciones a nivel de CALayer se ejecutan en la GPU, mientras que draw(_:) funciona mediante renderizado Core Graphics basado en CPU. Para animaciones y transiciones suaves, es preferible usar CALayer y CABasicAnimation.

EscenarioEnfoque recomendadoRendimiento
Esquinas redondeadaslayer.cornerRadiusGPU, alto
Sombras y degradadosCAGradientLayer, shadowPathGPU, alto
Formas arbitrariasCAShapeLayer con UIBezierPathGPU, alto
Gráficos complejosdraw(_:) con Core GraphicsCPU, medio
Texto con formato personalizadoCATextLayer o draw(_:)Depende del volumen

Use CAShapeLayer para dibujar formas vectoriales con animación — está acelerado por hardware y admite animación de path, strokeStart y strokeEnd sin llamar a draw(_:).

Optimización del rendimiento de Custom UIView

El rendimiento de Custom UIView afecta directamente la suavidad de las animaciones y la experiencia general del usuario. Los principales problemas surgen de llamadas excesivas a draw(_:), disposición subóptima de subvistas y falta de almacenamiento en caché.

Evite redibujados innecesarios

Cada llamada a setNeedsDisplay() provoca un redibujado completo de la vista. Use setNeedsDisplay(_:) con un rectángulo específico si los cambios solo afectaron a una parte de la vista. Para propiedades de CALayer (backgroundColor, cornerRadius, shadow), no se requiere redibujado — se actualizan a nivel de GPU.

Almacenamiento en caché del contenido renderizado

Si el contenido de Custom UIView cambia con poca frecuencia, renderícelo una vez en UIGraphicsImageRenderer y guárdelo como UIImage. En el próximo redibujado, use draw(at:) para mostrar la imagen en caché — esto es decenas de veces más rápido que volver a renderizar mediante Core Graphics.

swift
func renderToImage() -> UIImage {
    let renderer = UIGraphicsImageRenderer(size: bounds.size)
    return renderer.image { ctx in
        drawHierarchy(in: bounds, afterScreenUpdates: true)
    }
}

Use shouldRasterize para capas estáticas

La propiedad shouldRasterize en CALayer activa el almacenamiento en caché de la representación en mapa de bits de la capa. Actívela para vistas estáticas con transparencia y sombras — esto reduce la carga de composición. Desactívela para vistas animadas: la caché se restablece en cada cambio y la rasterización solo degrada el rendimiento.

Preguntas frecuentes

¿Es obligatorio sobrescribir draw(_:) en Custom UIView?

No, draw(_:) solo es necesario para dibujo personalizado mediante Core Graphics. Si la vista se compone de subvistas estándar (UILabel, UIImageView) y usa CALayer, no es necesario sobrescribir draw(_:) — incluso mejorará el rendimiento.

¿Cómo agregar un Custom UIView a Storyboard?

Coloque un UIView normal en el lienzo, en el Identity Inspector especifique su clase en el campo Class. Si la clase está marcada como @IBDesignable, los cambios se mostrarán en tiempo real directamente en Storyboard.

¿Cuál es la diferencia entre init(frame:) e init(coder:)?

init(frame:) se llama al crear la vista mediante programación — se pasa un CGRect con posición y tamaño. init(coder:) se llama al deserializar desde Storyboard o XIB. Para un funcionamiento correcto, ambos deben estar implementados; de lo contrario, su vista fallará al cargar desde Interface Builder.

¿Por qué no se llama a draw(_:)?

La razón más común es que la vista tiene un marco cero (ancho o alto igual a cero). El sistema no llama a draw(_:) para vistas con dimensiones cero. Verifique el marco en layoutSubviews() y asegúrese de que la vista se haya agregado a la jerarquía con restricciones correctas.

¿Cómo actualizar el contenido de Custom UIView sin redibujar completamente?

Use CALayer para propiedades que admiten animación en GPU (position, opacity, transform). Para actualizaciones parciales de draw(_:), use setNeedsDisplay(_:) con un CGRect del área modificada — el sistema solo redibujará la región especificada, no toda la vista.

Resumen

  • Custom UIView — una subclase de UIView con métodos sobrescritos para dibujo personalizado, se usa cuando los componentes estándar de UIKit son insuficientes
  • draw(_:) — método para dibujo personalizado mediante Core Graphics, llamado automáticamente por el sistema; está prohibido llamarlo directamente
  • CALayer — enfoque preferido para gráficos acelerados por GPU (sombras, redondeos, formas), una alternativa a draw(_:) con mayor rendimiento
  • init(frame:) e init(coder:) — inicializadores requeridos; ambos deben implementarse para un funcionamiento correcto desde código y Storyboard
  • setNeedsDisplay() — señal al sistema para volver a llamar a draw(_:); use la sobrecarga con CGRect para redibujado parcial
  • @IBDesignable — atributo para vista previa en vivo de Custom UIView en Interface Builder, simplifica el desarrollo visual
  • Para gráficos estáticos, guarde en caché el resultado mediante UIGraphicsImageRenderer y dibuje la imagen preparada — esto reduce la carga de CPU

Desarrollaremos una aplicación móvil llave en mano

IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.

Discutir el proyecto

Lea también