Antes de la introducción de SwiftUI, todas las aplicaciones en iOS estaban desarrolladas usando UIKit junto a una colección de framework basados y suportados por UIKit. A pesar de que en SwiftUI tenemos una gran colección de componentes para crear una aplicación, hay casos en los que no existe un equivalente SwiftUI a las opciones proporcionadas por los otros frameworks.
Debido al gran número de apps que han sido desarrolladas antes de la introduccion de SwiftUI, es importante ser capaz de integrar funcionalidades no-SwiftUI con proyectos desarrollados en SwiftUI y viceversa. Afortunadament SwiftUI incluye muchas opciones para hacer este tipo de integración.
Antes de entrar en detalles de como integrar SwiftUI y UIKit vale la pena tomarse un tiempo para explorar si un nuevo proyecto debe ser empezado usando UIKit o SwiftUI y si una aplicación debe ser migrada completamente a SwiftUI. Cuando tengas que tomar esta decision ten en cuenta que las aplicaciones en SwiftUI solo pueden usarse en dispositivos con iOS 13 o superior.
Si estás empezando un nuevo proyecto, entonces lo mejor sería crear la app en SwiftUI e integrar UIKit cuando la funcionalidad no sea proporcionada directamente por SwiftUI. Si estás pensando si debes aprender SwiftUI o UIKit te recomiendo que leas este artículo: SwiftUI vs UIKit ¿Que framework de Apple deberías aprender?
Al desarrollar aplicaciones iOS con Storyboard en Xcode, se utiliza UIKit para todos los aspectos de la interfaz de usuario. UIKit es el framework que conforma los componentes principales de todas las aplicaciones iOS. Entre todas las clases de UIKit, las vistas y los controladores de vista son las más utilizadas.
Los controladores de vista (UIViewController) desempeñan un papel crucial en las aplicaciones, ya que actúan como el esqueleto de la misma. Un controlador de vista es básicamente una clase que gestiona un conjunto de vistas (para mostrar al usuario) y se coordina con los objetos del modelo (datos).
Los distintos widgets, como Button, Label, TextField y Switch, están representados por las subclases de UIView.
Algunas de las clases UIKit se utilizan para ejecutar la aplicación (UIApplication), para cargar imágenes (UIImage), para administrar el dispositivo (UIDevice), la ventana (UIWindow) y algunas para definir los delegates que usamos para configurar la aplicación y las escenas (UIApplicationDelegate y UIWindowSceneDelegate) pero el framework también define dos clases básicas para crear y administrar vistas, UIView y UIViewController.
Las subclases de la clase UIView están diseñadas para presentar información en pantalla, como etiquetas o imágenes, o controles como botones, deslizadores o interruptores. Las subclases de la clase UIViewController están diseñadas para gestionar toda la interfaz de una pantalla. Presentan las vistas para mostrar la información e incluyen la funcionalidad necesaria para procesar sus valores e interactuar con el usuario.
A pesar de que Apple continua soportando UIKit para el desarrollo de aplicaciones, esta claro que para Apple, el framework SwiftUI es el futuro. SwiftUI tambien hace más fácil desarrollar aplicaciones para iOS, macOS, tvOS, iPadOS y watchOS sin hacer muchos cambios en el código.
Si, por otro lado, tienes proyectos existentes que son anteriores a la introducción de SwiftUI entonces probablemente tenga sentido dejar el código existente sin cambiar, construir futuras adiciones al proyecto usando SwiftUI e integrar estas adiciones a tu base de código existente.
Para aquellos que no están familiarizados con UIKit, una pantalla mostrada en una app es tipicamente implementada usando un view controller (implementados como una instancia de UIViewController o una subclase de la misma.
Creando una struct que se ajuste a UIViewRepresentable
Los componentes individuales que conforman la interfície de usuario de una aplicación basada en UIKit son derivados de la clase UIView. Botones, etiquetas, vistas de texto, mapas, sliders (para nombrar unos cuantos) son todos subclases de la clase de UIKit, UIView.
Para facilitar la integración de un componente basado en UIView en una declaración de vista de SwiftUI, SwiftUI tiene el protocolo UIViewRepresentable. Para integrar un componente de UIView en SwiftUI, este componente necesita estar envuelto en una estructura que implemente este protocolo.
El protocolo UIViewRepresentable define una estructura que actúa como contenedor para los objetos creados a partir de la clase UIView y sus subclases. Una estructura que cumple con este protocolo puede presentar una vista UIKit dentro de una interfaz SwiftUI.
Como mínimo, la estructura del contenedor debe implementar los siguientes métodos para cumplir con el protocolo UIViewRepresentable:
makeUIView() : Este método es el responsable para crear la instancia del componente basado en la UIView, realizando cualquier implementación necesaria y retornandolo.
updateView() : Llamado cada vez que un cambio ocurre dentro de la vista SwiftUI contenedora que requiere que UIView se actualice a sí misma.
El siguiente método también puede ser implementado:
dismantleUIView() : Proporciona una oportunidad para realizar operaciones de limpieza antes de que se elimine la vista.
Para incluir un objeto UIView, o un objeto creado a partir de cualquiera de sus subclases, en una interfaz SwiftUI, debemos definir una estructura que cumpla con el protocolo UIViewRepresentable e implementar estos métodos. Los métodos makeUIView() y updateUIView() son obligatorios. En el método makeUIView(), debemos crear la instancia de la vista UIKit y devolverla. Podemos usar el método updateUIView() para actualizar la vista con valores provenientes de la interfaz SwiftUI, como los valores insertados por el usuario en un campo de texto, por ejemplo. Este método también se llama cuando hay cambios en la vista representable, por lo que podemos usarlo para actualizar la vista cuando cambia la orientación de la pantalla.
Si queremos enviar valores desde la vista UIKit a la interfaz SwiftUI, debemos implementar el método makeCoordinator(). A partir de este método, debemos crear una instancia de un objeto coordinador y devolverla.
Ejemplo de como usar UIKit en SwiftUI
Vamos a ver un ejemplo para entender como integrar UIKit en SwiftUI.
Supongamos que existe una característica de la clase UILabel que no está disponible en la vista de texto de SwiftUI. Para encapsular una vista UILabel con UIViewRepresentable y que pueda usarse en SwiftUI, la estructura podría implementarse de la siguiente manera:
import SwiftUI
struct MyUILabel: UIViewRepresentable {
var text: String
func makeUIView(context: UIViewRepresentableContext<MyUILabel>) -> UILabel {
let myLabel = UILabel()
myLabel.text = text
return myLabel
}
func updateUIView(_ uiView: UILabel, context: UIViewRepresentableContext<MyUILabel>) {
}
}
Con la vista UILabel encapsulada, ahora se puede hacer referencia a ella dentro de SwiftUI como si fuera un componente SwiftUI integrado:
struct ContentView: View {
var body: some View {
MyUILabel(text: "Hello UIKit from SwiftUI!")
}
}
Que en Xcode daría el siguiente resultado:

Obviamente, UILabel es un componente estático que no necesita gestionar eventos de interacción del usuario. Sin embargo, para las vistas que deben responder a eventos, es necesario extender el contenedor UIViewRepresentable para implementar un coordinador.
Si tienes cualquier duda sobre este artículo, contacta conmigo y estaré encantado de ayudarte 🙂. Puedes contactar conmigo en mi perfil de X o en mi perfil de Instagram.