Lição: 104: Coordenadores e UIViewRepresentable
No mundo do SwiftUI, UIViewRepresentable
oferece uma maneira de integrar views do UIKit em suas aplicações SwiftUI. No entanto, ao fazer a ponte entre UIKit e SwiftUI, você frequentemente encontrará a necessidade de uma melhor gestão de estado e interações do usuário. É aqui que o conceito de Coordenadores se torna relevante.
O que é UIViewRepresentable?
UIViewRepresentable
é um protocolo que permite criar uma view SwiftUI que encapsula uma view do UIKit. Isso é especialmente útil quando você deseja utilizar componentes existentes do UIKit ou quando precisa aproveitar funcionalidades que não estão disponíveis no SwiftUI.
Vamos começar entendendo como criar um simples UIViewRepresentable
.
Exemplo Básico de UIViewRepresentable
Neste exemplo, criaremos um simples wrapper em torno de um UILabel
.
import SwiftUI
struct UILabelRepresentable: UIViewRepresentable {
var texto: String
func makeUIView(context: Context) -> UILabel {
let label = UILabel()
label.textAlignment = .center
return label
}
func updateUIView(_ uiView: UILabel, context: Context) {
uiView.text = texto
}
}
struct ContentView: View {
var body: some View {
UILabelRepresentable(texto: "Olá, UIKit!")
.padding()
.font(.largeTitle)
}
}
Neste código:
makeUIView
é chamado apenas uma vez para criar a instância inicial doUILabel
.updateUIView
é chamado quando o estado do SwiftUI muda e permite que você atualize a view.
O que é um Coordenador?
Os Coordenadores atuam como uma ponte entre SwiftUI e UIKit. Eles ajudam a gerenciar interações do usuário e métodos delegados de maneira mais estruturada, especialmente ao trabalhar com componentes complexos do UIKit.
Integrando um Coordenador com UIViewRepresentable
Vamos aprimorar nosso exemplo anterior adicionando um botão que altera o texto do rótulo quando pressionado. Para isso, introduziremos um Coordenador.
import SwiftUI
struct UILabelRepresentable: UIViewRepresentable {
@Binding var texto: String
class Coordenador: NSObject {
var pai: UILabelRepresentable
init(pai: UILabelRepresentable) {
self.pai = pai
}
@objc func botaoPressionado() {
// Alterar o texto quando o botão é pressionado
pai.texto = "Botão Pressionado!"
}
}
func makeCoordinator() -> Coordenador {
Coordenador(pai: self)
}
func makeUIView(context: Context) -> UIView {
let stackView = UIStackView()
stackView.axis = .vertical
stackView.alignment = .center
let label = UILabel()
label.textAlignment = .center
label.text = texto
let botao = UIButton(type: .system)
botao.setTitle("Clique em Mim", for: .normal)
botao.addTarget(context.coordinator, action: #selector(Coordenador.botaoPressionado), for: .touchUpInside)
stackView.addArrangedSubview(label)
stackView.addArrangedSubview(botao)
return stackView
}
func updateUIView(_ uiView: UIView, context: Context) {
if let stackView = uiView as? UIStackView,
let label = stackView.arrangedSubviews.first as? UILabel {
label.text = texto
}
}
}
struct ContentView: View {
@State private var textoDoLabel = "Olá, UIKit!"
var body: some View {
UILabelRepresentable(texto: $textoDoLabel)
.padding()
.font(.largeTitle)
}
}
Explicação
-
Classe Coordenador:
- A classe
Coordenador
gerencia as interações e mantém uma referência ao paiUILabelRepresentable
. - O método
botaoPressionado
lida com o evento de pressão do botão, atualizando o texto.
- A classe
-
makeCoordinator():
- Esta função cria uma instância do coordenador que será usada para lidar com as interações.
-
Criação da UIView:
- Em
makeUIView
, criamos umUIStackView
que contém o rótulo e o botão. - A ação do botão é conectada ao método
botaoPressionado
no coordenador.
- Em
-
Atualizando a View:
- Em
updateUIView
, atualizamos o texto do rótulo sempre que a bindingtexto
muda.
- Em
Conclusão
Usar UIViewRepresentable
em conjunto com um Coordenador permite gerenciar efetivamente as interações entre SwiftUI e UIKit. Essa abordagem mantêm uma clara separação de responsabilidades e aproveita o melhor de ambos os frameworks. À medida que você projeta interfaces mais complexas, entender como usar Coordenadores permitirá que você integre componentes do UIKit perfeitamente em seus projetos SwiftUI.