Skip to content

Cómo utilizar Xcode Previews con UIKit Views

18 febrero, 2021

Una de las herramientas más poderosas de SwiftUI son las Live Previews. Me fascina ese momento mágico en el que modificas algo en código y se refleja automáticamente en el Canvas, sin necesidad de compilar o lanzar la aplicación.

Durante las últimas semanas he estado jugando con SwiftUI y, obviamente, hice un uso extensivo de las Live Previews. Cuando me tocó volver a utilizar UIKit, sea con sus ficheros XIB o directamente en código, teniendo que compilar una y otra vez con cada mínimo cambio, pensé: «Tiene que haber una forma más inteligente de hacer todo esto».

Es así como cree un simple pero poderoso SwiftUI wrapper para poder editar en tiempo real una UIView o un UIViewController y que los cambios se reflejen instantáneamente en el Live Preview:

¿Qué necesitamos?

La idea es simple: tenemos que ser capaces de mostrar vistas o controladores escritos con UIKit en SwiftUI. Para ello necesitamos dos wrappers: uno para las UIView y otro para los UIViewController.

La sintaxis que me gustaría poder utilizar en las Live Previews con UIKit es la siguiente:

struct ProfileViewController_Previews: PreviewProvider {
    static var previews: some View {
        ViewControllerPreview {
            ProfileViewController()
        }
    }
}

Esto es importante ya que de ello depende la forma que tendrán nuestros wrappers.

Utilizar Xcode Previews con UIViewControllers

Para poder mostrar un UIViewController en SwiftUI, tenemos que hacer uso del protocolo UIViewControllerRepresentable.

Para ello creamos un struct llamado ViewControllerPreview que acepta un closure de tipo () -> UIViewController, y así poder tener la sintaxis deseada gracias a los trailing closures:

import UIKit
import SwiftUI

struct ViewControllerPreview: UIViewControllerRepresentable {
    let viewControllerBuilder: () -> UIViewController

    init(_ viewControllerBuilder: @escaping () -> UIViewController) {
        self.viewControllerBuilder = viewControllerBuilder
    }

    func makeUIViewController(context: Context) -> some UIViewController {
        return viewControllerBuilder()
    }

    func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
        // Nothing here
    }
}

Utilizar Xcode Previews con UIViews

En el caso de querer mostrar un UIView en SwiftUI hacemos uso de UIViewRepresentable.

Para ello, creamos un struct llamado ViewPreview que acepta un closure de tipo () -> UIView. Ya sabes, para tener la sintaxis del trailing closure:

import UIKit
import SwiftUI

struct ViewPreview: UIViewRepresentable {
    let viewBuilder: () -> UIView

    init(_ viewBuilder: @escaping () -> UIView) {
        self.viewBuilder = viewBuilder
    }

    func makeUIView(context: Context) -> some UIView {
        viewBuilder()
    }

    func updateUIView(_ uiView: UIViewType, context: Context) {
        // Nothing here
    }
}

Utilizando Xcode Live Preview con UIKit

Para mostraros cómo funciona, he creado un sencillo UIViewController llamado ProfileViewController. En él, añado un AvatarView y lo centro en la pantalla:

import UIKit
import SwiftUI

final class ProfileViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let avatarView = AvatarView()
        view.addSubview(avatarView)

        avatarView.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            avatarView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            avatarView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            avatarView.widthAnchor.constraint(equalTo: view.widthAnchor),
            avatarView.heightAnchor.constraint(equalTo: view.widthAnchor),
        ])
}

struct ProfileViewController_Previews: PreviewProvider {
    static var previews: some View {
        ViewControllerPreview {
            ProfileViewController()
        }
    }
}

A continuación, modificamos el ProfileViewController a nuestro antojo, y vemos cómo los cambios se reflejan en el Canvas, de la misma forma que si estuviésemos utilizando SwiftUI. He creado un pequeño video con la secuencia:

También me he animado, después de dos años sin hacerlo, a subir un video a YouTube con el tutorial:

https://www.youtube.com/watch?v=2TKR4kU1CEc
Atajos Xcode

Descarga GRATIS la chuleta de atajos de Xcode

He creado una chuleta en PDF con los 35 shortcuts de Xcode que todo iOS developer debe conocer.  Tenlos todos juntos y a mano para poder consultarlos en cualquier momento 🙂 

Déjame tus datos y te la enviaré a tu correo electrónico. 

Conclusión

Se acabó tener que compilar una y otra vez con cada pequeño cambio mientras creas tu UI. Siempre que puedas tener un target +iOS13, podrás hacer uso de las Live Previews, ya sea con SwiftUI o con UIKit.

Si te ha gustado, me ayudaría mucho que compartieses el post en tus redes sociales para poder llegar a más gente.

👇👇👇


¿Me ayudas a compartir en redes sociales?