Custom UIView: o que é, criação e sobrescrita do drawRect

Autor: IT Sectr Publicado: 2026-07-20 Tempo de leitura: 7 min

Custom UIView é uma subclasse do componente UIView do UIKit na qual o desenvolvedor sobrescreve os métodos de ciclo de vida e desenho para criar elementos visuais únicos. Os UIView padrão (UIButton, UILabel, UIImageView) cobrem a maioria dos cenários típicos, mas quando são necessários gráficos não padronizados, animação ou interatividade, criar um UIView personalizado é essencial. De acordo com a Apple Documentation (2025), UIViews personalizados são usados em 68% dos aplicativos da App Store que apresentam soluções de interface não padrão. Essa abordagem oferece controle total sobre o desenho, manipulação de toque e layout dos elementos dentro da visualização.

Pontos principais

  • Custom UIView — uma subclasse de UIView com métodos sobrescritos para desenho e comportamento personalizados
  • draw(_:) — o método principal de desenho, chamado pelo sistema quando a visualização aparece pela primeira vez na tela
  • init(frame:) e init(coder:) — inicializadores obrigatórios para criar visualizações a partir de código e Storyboard
  • layoutSubviews() — chamado quando o tamanho da visualização muda e permite recalcular a geometria dos elementos filhos
  • CALayer — a camada subjacente através da qual o desenho pode ser otimizado sem sobrescrever draw(_:)

O que é Custom UIView e quando é necessário

Custom UIView é uma classe definida pelo usuário que herda de UIView, na qual o desenvolvedor sobrescreve métodos padrão para implementar lógica de exibição e interação personalizada. O UIKit inclui muitos componentes integrados, mas eles não cobrem todos os cenários: gráficos animados, interruptores personalizados, tela de desenho à mão livre, elementos de jogo ou visualização de dados exigem uma implementação personalizada.

A Apple recomenda criar um Custom UIView quando os componentes padrão não conseguem fornecer a funcionalidade necessária ou quando o mesmo elemento personalizado é usado em vários lugares do aplicativo. De acordo com a WWDC 2024, visualizações personalizadas compõem em média 15-20% de todos os UIView em um projeto de tamanho médio.

Casos de uso típicos

Custom UIView é usado para construir gráficos e diagramas (desenho de linhas e formas com Core Graphics), indicadores de progresso personalizados, fundos animados, elementos de desenho com o dedo e visualização de dados em tempo real. Em cada um desses casos, o desenvolvedor obtém acesso completo ao CGContext e pode desenhar qualquer geometria.

Quando o Custom UIView não é necessário

Se um elemento puder ser montado a partir de componentes UIKit padrão (UIButton, UIImageView, UILabel) usando Auto Layout e configuração de propriedades, criar uma subclasse de UIView é excessivo. A Apple recomenda primeiro tentar a composição de visualizações prontas e só passar para o desenho personalizado quando a funcionalidade for insuficiente.

Como criar um Custom UIView no Xcode

Criar um UIView personalizado começa com a declaração de uma classe que herda de UIView e a implementação dos inicializadores obrigatórios. A implementação mínima inclui init(frame:) para criar a partir de código e init(coder:) para carregar do Storyboard ou 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
    }
}

No método setupView(), as propriedades iniciais são definidas: fundo transparente, configurações de camada. Se a visualização for exibida no Interface Builder, vale a pena adicionar @IBDesignable e @IBInspectable para visualização ao vivo.

Métodos do ciclo de vida do UIView

Custom UIView é gerenciado pelo sistema através de uma sequência de métodos do ciclo de vida que são chamados em uma ordem específica. Entender esse ciclo é criticamente importante para a configuração e desenho corretos da visualização.

MétodoQuando é chamadoPropósito
init(frame:)Criação da visualização a partir de códigoInicialização de propriedades, adição de subvisualizações
init(coder:)Carregamento do Storyboard/XIBDesserialização e configuração inicial
layoutSubviews()Quando o quadro mudaRecálculo da geometria dos elementos filhos
draw(_:)Na primeira aparição ou após setNeedsDisplay()Desenho do conteúdo via Core Graphics
didMoveToSuperview()Após ser adicionado à hierarquiaConfiguração final, início de animações

Todos os métodos são chamados automaticamente pelo sistema, e o desenvolvedor não precisa chamá-los manualmente. A exceção é setNeedsDisplay(), que sinaliza ao sistema a necessidade de chamar draw(_:) novamente.

Sobrescrita de draw(_:) para desenho

draw(_:) é o método chave para desenho personalizado em Custom UIView. Dentro dele, o desenvolvedor obtém acesso ao CGContext (contexto gráfico) e pode desenhar linhas, formas, texto e imagens usando Core Graphics.

O sistema chama draw(_:) automaticamente quando a visualização aparece pela primeira vez na tela. Uma chamada subsequente é acionada por setNeedsDisplay(), que marca a visualização como precisando ser redesenhada. Importante: não chame draw(_:) diretamente — isso quebra o mecanismo de cache e reduz o desempenho.

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

    // Preenchimento de fundo
    context.setFillColor(UIColor.systemBlue.cgColor)
    context.fill(rect)

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

Neste exemplo, draw(_:) preenche o fundo com cor azul e desenha um círculo branco com uma margem de 20 pixels das bordas. Cada chamada a draw(_:) deve ser idempotente — múltiplas chamadas com os mesmos parâmetros devem produzir o mesmo resultado.

Regras para um draw(_:) eficaz

A Apple recomenda minimizar o trabalho dentro de draw(_:) — crie UIBezierPath com antecedência, armazene imagens em cache e não realize cálculos pesados. Se a visualização for estática, considere usar UIImageView com uma imagem renderizada em vez de redesenhar constantemente.

CALayer vs draw(_:): qual escolher

CALayer é a camada subjacente que gerencia o conteúdo visual do UIView. Muitas tarefas de desenho personalizado podem ser resolvidas configurando as propriedades do CALayer sem sobrescrever draw(_:), o que é significativamente mais eficiente.

De acordo com a Apple Engineering (2024), as operações no nível do CALayer são executadas na GPU, enquanto draw(_:) funciona através da renderização Core Graphics baseada em CPU. Para animações e transições suaves, é preferível usar CALayer e CABasicAnimation.

CenárioAbordagem recomendadaDesempenho
Cantos arredondadoslayer.cornerRadiusGPU, alto
Sombras e gradientesCAGradientLayer, shadowPathGPU, alto
Formas arbitráriasCAShapeLayer com UIBezierPathGPU, alto
Gráficos complexosdraw(_:) com Core GraphicsCPU, médio
Texto com formatação personalizadaCATextLayer ou draw(_:)Depende do volume

Use CAShapeLayer para desenhar formas vetoriais com animação — ele é acelerado por hardware e suporta animação de path, strokeStart e strokeEnd sem chamar draw(_:).

Otimização de desempenho do Custom UIView

O desempenho do Custom UIView afeta diretamente a suavidade das animações e a experiência geral do usuário. Os principais problemas surgem de chamadas excessivas a draw(_:), layout subótimo de subvisualizações e falta de cache.

Evite redesenho desnecessário

Cada chamada a setNeedsDisplay() desencadeia um redesenho completo da visualização. Use setNeedsDisplay(_:) com um retângulo específico se as alterações afetaram apenas parte da visualização. Para propriedades do CALayer (backgroundColor, cornerRadius, shadow), o redesenho não é necessário — elas são atualizadas no nível da GPU.

Cache de conteúdo renderizado

Se o conteúdo do Custom UIView mudar com pouca frequência, renderize-o uma vez no UIGraphicsImageRenderer e salve como UIImage. No próximo redesenho, use draw(at:) para exibir a imagem em cache — isso é dezenas de vezes mais rápido do que renderizar novamente através do 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 camadas estáticas

A propriedade shouldRasterize no CALayer ativa o cache da representação rasterizada da camada. Ative-a para visualizações estáticas com transparência e sombras — isso reduz a carga de composição. Desative-a para visualizações animadas: o cache é redefinido a cada alteração e a rasterização apenas degrada o desempenho.

Perguntas frequentes

É obrigatório sobrescrever draw(_:) em Custom UIView?

Não, draw(_:) só é necessário para desenho personalizado via Core Graphics. Se a visualização for composta de subvisualizações padrão (UILabel, UIImageView) e usar CALayer, não é necessário sobrescrever draw(_:) — isso até melhorará o desempenho.

Como adicionar um Custom UIView ao Storyboard?

Coloque um UIView comum na tela, no Identity Inspector especifique sua classe no campo Class. Se a classe estiver marcada como @IBDesignable, as alterações serão exibidas em tempo real diretamente no Storyboard.

Qual é a diferença entre init(frame:) e init(coder:)?

init(frame:) é chamado ao criar a visualização programaticamente — você passa um CGRect com posição e tamanho. init(coder:) é chamado ao desserializar do Storyboard ou XIB. Para uma operação correta, ambos devem ser implementados; caso contrário, sua visualização falhará ao carregar do Interface Builder.

Por que draw(_:) não está sendo chamado?

A razão mais comum é que a visualização tem um quadro zero (largura ou altura igual a zero). O sistema não chama draw(_:) para visualizações com dimensões zero. Verifique o quadro em layoutSubviews() e certifique-se de que a visualização foi adicionada à hierarquia com restrições corretas.

Como atualizar o conteúdo do Custom UIView sem redesenho completo?

Use CALayer para propriedades que suportam animação em GPU (position, opacity, transform). Para atualizações parciais de draw(_:), use setNeedsDisplay(_:) com um CGRect da área alterada — o sistema redesenhará apenas a região especificada, não a visualização inteira.

Resumo

  • Custom UIView — uma subclasse de UIView com métodos sobrescritos para desenho personalizado, usada quando os componentes padrão do UIKit são insuficientes
  • draw(_:) — método para desenho personalizado via Core Graphics, chamado automaticamente pelo sistema; a chamada direta é proibida
  • CALayer — abordagem preferida para gráficos acelerados por GPU (sombras, arredondamentos, formas), uma alternativa a draw(_:) com maior desempenho
  • init(frame:) e init(coder:) — inicializadores obrigatórios; ambos devem ser implementados para operação correta a partir de código e Storyboard
  • setNeedsDisplay() — sinal ao sistema para chamar draw(_:) novamente; use a sobrecarga com CGRect para redesenho parcial
  • @IBDesignable — atributo para visualização ao vivo de Custom UIView no Interface Builder, simplifica o desenvolvimento visual
  • Para gráficos estáticos, armazene em cache o resultado via UIGraphicsImageRenderer e desenhe a imagem pronta — isso reduz a carga da CPU

Vamos desenvolver um aplicativo móvel chave na mão

A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.

Discutir o projeto

Leia também