SwiftUI ofrece un enfoque declarativo para el diseño de la interfaz de usuario. Con un enfoque imperativo tradicional, como el que teníamos en UIKit por ejemplo, la carga recae en el código del controlador no solo para crear instancias, diseñar y configurar vistas, sino también para realizar actualizaciones continuamente a medida que cambian las condiciones. 

Por el contrario, con un enfoque declarativo, se crean descripciones de la interfaz de usuario declarando vistas en una jerarquía que refleja el diseño deseado de la interfaz. Luego, SwiftUI administra el pintado y la actualización de estas vistas en respuesta a eventos que se producen en la aplicación, como la entrada de datos del usuario o los cambios de estado propios del ciclo de vida de la aplicación.

SwiftUI proporciona herramientas para definir y configurar las vistas en la interfaz de usuario. Compone vistas personalizadas o compuestas a partir de las vistas integradas que proporciona el propio framework de SwiftUI, además de otras vistas compuestas que ya se hayan definido con anterioridad. 

Estas vistas se pueden modificar gracias a los modificadores de vista y conectarlas a los modelos de datos. Luego solo nos queda posicionar nuestras vistas personalizadas dentro de la jerarquía de vistas padre donde queramos que se muestren.

Protocolo View, el eje de todas las interfaces en SwiftUI

Cualquier componente que forme parte de una vista que se desee mostrar al usuario debe de implementar el protocolo View.

struct MyView: View {
}

Al igual que otros protocolos de Swift , el protocolo View proporciona el comportamiento de un elemento de vista que SwiftUI dibuja en pantalla. Al implementar este protocolo, toda vista necesita crear una variable body de tipo some View en donde se deberá de escribir aquel código que renderize nuestra vista. En general dentro de la variable body existirán se crearán instancias de otras vistas que al igual que esta, implementarán el protocolo View.

struct MyView: View {
    var body: some View {
    }
}

Básicamente una vista está compuestas de otras vistas. Toda vista se genera por composición de otras vistas.

SwiftUI lee el valor de esta propiedad cada vez que necesita actualizar la vista, lo que puede ocurrir repetidamente durante la vida de la vista, generalmente en respuesta a la entrada de datos del usuario o eventos diversos del sistema. El valor que devuelve la vista es un elemento que SwiftUI dibuja en pantalla.

El requisito secundario del protocolo es que los tipos conformes con él deben indicar un tipo asociado para la propiedad del cuerpo. Sin embargo, no haces una declaración explícita. En su lugar, declara la propiedad del cuerpo como un tipo opaco , usando la some View sintaxis, para indicar solo que el tipo del cuerpo se ajusta a View. El tipo exacto depende del contenido del cuerpo, que varía a medida que edita el cuerpo durante el desarrollo. Swift infiere el tipo exacto automáticamente.

Es decir, si queremos crear un texto, dentro de la propiedad body, intanciamos el componente del framework de SwiftUI Text(), componente que también implementa el protocolo View. Nuestra variable body, retornará un tipo some View por defecto, que en nuestro caso será Text, y que el compilador inferirá cuando sea necesario, pero nuestra variable body no definirá Text como tipo de retorno.

struct MyView: View {
    var body: some View {
        Text("Hello, World!")
    }
}

Componiendo vistas en SwiftUI

Las apariencias de las vistas se crean agregando contenido a la propiedad del cuerpo de la vista tal como hemos indicado antes. Se puede componer el cuerpo a partir de vistas integradas que proporciona SwiftUI, así como vistas personalizadas que haya definido en otra parte de la aplicación. Por ejemplo, puede crear un cuerpo que dibuje la cadena «¡Hola, mundo!» usando una vista  Text como en el código anterior que dará como resultado:

Además de las vistas para tipos específicos de contenido, controles e indicadores, como TextToggle , etc.. , SwiftUI también proporciona vistas integradas que puede usar para organizar otras vistas. Por ejemplo, puede apilar verticalmente dos vistas usando un VStack:

struct MyView: View {
    var body: some View {
        VStack {
            Text("Hello, World!")
            Text("Glad to meet you.")
        }
    }
}

Modificadores de vistas en SwiftUI

Para configurar/modificar las vistas que existen dentro del cuerpo de la vista, se pueden aplicar los llamados modificadores de vista. Un modificador no es más que un método llamado en una vista particular. El método devuelve una nueva instancia de la vista modificada que efectivamente ocupa el lugar de la original en la jerarquía de vistas.

Recordemos que todas las vistas en SwiftUI son struct y por tanto son componentes inmutables. Por tanto cuando se aplica un modificador a una vista lo que el sistema hace es crear una copia de la anterior aplicándole el modificador al que llamamos.

SwiftUI incluye un gran abanico de modificadores para todas las vistas que implementen el protocolo  View . Todos estas vistas tienen acceso a estos métodos que alteran el comportamiento de una vista de alguna manera. Por ejemplo, puede cambiar la fuente de una vista de texto aplicando el modificador font(_:)

struct MyView: View {
    var body: some View {
        VStack {
            Text("Hello, World!")
                .font(.title)
            Text("Glad to meet you.")
        }
    }
}

Por último, esta vista nueva que hemos creado, MyView, la podemos utilizar como hijo de otra vista padre en nuestro proyecto, tan sencillo como:

struct OtherView: View {
    var body: some View {
        MyView()
    }
}

De esta forma vamos creando pequeños componentes que luego podemos ir utilizando para componer las diferentes partes de nuestras vistas y reutilizarlos en múltiples sitios.