Introducción al curso

1

Construyamos una app para iOS

2

Introducción a la arquitectura MVVM

3

Planeando nuestra app

Creando las primeras pantallas de la app

4

Programando la primera pantalla en módulos

5

Escribiendo la lógica para mostrar dos pantallas

6

Pantalla de inicio de sesión con SecureField y Scroll

7

Completando nuestra pantalla de inicio de sesión

8

Pantalla de registro de usuario

9

Comprobando el funcionamiento de nuestras pantallas

10

Estructura de las pantallas con TabView

11

Creando nuestra pantalla home

12

Pantalla home: logo y barra de búsqueda

13

Pantalla home: programación de interfaces estáticas

14

Pantalla home: carruseles

Aplicando arquitectura MVVM

15

Creando estructura para arquitectura MVVM

16

Modelando nuestro JSON

17

Peticiones al servidor

18

Mostrar información de un servidor de manera dinámica

19

Mostrar imágenes de forma dinámica y eficiente con LazyVGrid

Reproductor y búsqueda de video

20

Pasar datos entre pantallas

21

Darle datos de inicio a un Canvas

22

Reproducir videos dinámicamente de un servidor

23

Mostrar imágenes dinámicamente de un servidor

24

Mostrar alertas

25

Programar clase de búsqueda

26

Programar método de búsqueda

Últimas pantallas de la app

27

Pantalla de favoritos

28

Pantalla de perfil de usuario

29

Módulo de ajustes de perfil con Toggle

30

Pantalla de edición de perfil

31

Módulo de edición de perfil

32

Guardado interno de datos

Utilizando la cámara y fotos del iPhone

33

Captura de foto de perfil: ImagePicker y vista Sheet

34

Captura de foto de perfil con la cámara: modificar librerías de terceros

35

Captura de foto de perfil con la cámara: recuperar imágenes guardadas

¿Qué más posibilidades tiene SwiftUI?

36

Mejoremos nuestra app

No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Pantalla home: carruseles

14/36
Recursos

Aportes 8

Preguntas 3

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

Para los que vean esto en Xcode 16.0+
Los NavigationLink quedarían de la siguiente manera:
Primera parte del reproductor.

NavigationLink {
                VideoPlayer(player: AVPlayer(url: URL(string: url)!)).frame(width: 420, height: 360, alignment: .center)
            } label: {
                ZStack{
                    Button {
                        url = urlVideos[0]
                        print("URL: \(url)")
                        isPlayerActive = true
                    } label: {
                        VStack(spacing: 0){
                            Image("The Witcher 3")
                                .resizable()
                                .scaledToFill()
                            Text("The Witcher 3")
                                .foregroundColor(.white)
                                .frame(maxWidth: .infinity, alignment: .leading)
                                .background(Color("blue-gray"))
                        }
                    }
                    Image(systemName: "play.circle.fill")
                        .resizable()
                        .foregroundColor(.white)
                        .frame(width: 42, height: 42)

                }.frame(minWidth: 0, maxWidth: .infinity, alignment: .center)
                    .padding(.vertical)
            }

Carrusel de imágenes de videojuegos.

ScrollView(.horizontal, showsIndicators: false){
                HStack{
                    NavigationLink {
                        VideoPlayer(player: AVPlayer(url: URL(string: urlVideos[1])!)).frame(width: 420, height: 360, alignment: .center)
                    } label: {
                        Image("Abzu")
                            .resizable()
                            .scaledToFit()
                            .frame(width: 240, height: 135)
                    }
                    
                    NavigationLink {
                        VideoPlayer(player: AVPlayer(url: URL(string: urlVideos[2])!)).frame(width: 420, height: 360, alignment: .center)
                    } label: {
                        Image("Crash Bandicoot")
                            .resizable()
                            .scaledToFit()
                            .frame(width: 240, height: 135)
                    }
                    
                    NavigationLink {
                        VideoPlayer(player: AVPlayer(url: URL(string: urlVideos[3])!)).frame(width: 420, height: 360, alignment: .center)
                    } label: {
                        Image("DEATH STRANDING")
                            .resizable()
                            .scaledToFit()
                            .frame(width: 240, height: 135)
                    }
                }
            }

No te funciona el scroll vertical?

ScrollView(showsIndicators: false){
    SubModuloHome()
 }

De nada.

Reto

Text("Videos que podrían gustarte")
    .font(.title3)
    .foregroundColor(.white)
    .bold()
    .frame(maxWidth: .infinity, alignment: .leading)

ScrollView(.horizontal, showsIndicators: false) {
    HStack  {
        Button(action: {
            url = urlVideos[4]
            print("URL:", url)
            isPlayerActive = true
        }) {
            Image("Grand Theft Auto V")
                .resizable()
                .scaledToFit()
                .frame(width: 240, height: 135)
        }
        
        Button(action: {
            url = urlVideos[5]
            print("URL:", url)
            isPlayerActive = true
        }) {
            Image("Hades")
                .resizable()
                .scaledToFit()
                .frame(width: 240, height: 135)
        }
    }
}
.padding(.bottom)

El código en structs para no repetir

struct TitleView:View {
    var title: String
    var body: some View{
        Text(title)
            .font(.title3)
            .foregroundColor(.white)
            .bold()
            .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
    }
}

struct CategoryCarrouselItem:View {
    var image, text: String
    var action: () -> Void
    var body: some View{
        Button(action: action, label: {
            ZStack{
                RoundedRectangle(cornerRadius: 8)
                    .fill(Color("BlueGray"))
                    .frame(width: 160, height: 90)
                
                VStack {
                    Image(image)
                    Image(text)
                }
            }
        })
        
    }
}

Si estas viendo esto después de iOS 16 lo mas probable es que te enfrentes con el problema de que al bajar el scroll tu TabView se ponga de color blanco. Y bueno después de andar investigando y probando diferentes soluciones encontré 2 que posiblemente te puedan servir.

Esconder el background del toolbar

Si seguiste el video del profesor e utilizaste el inicializador de las librerías antiguas (UIKit) la forma en la que resolví es agregar a cada tabItem la propiedad toolbarBackground(.hidden, for: .tabBar) te muestro el ejemplo:

TabView(selection: $selectedTab) {
	Text("Pantalla Perfil").tabItem {
		Image(systemName: "person")
		Text("Perfil")
	}.tag(0).toolbarBackground(.hidden, for: .tabBar)
	...
}

init() {
	UITabBar.appearance().backgroundColor = UIColor(Color("TabBar-Color"))
	UITabBar.appearance().isTranslucent = true
}

Modificar el toolbar de cada item

La otra forma que encontré es modificar cada tabItem con el color y hacerla visible en todo momento:

TabView(selection: $selectedTab) {
	Text("Pantalla Perfil").tabItem {
		Image(systemName: "person")
		Text("Perfil")
	}.tag(0).toolbarBackground(Color("TabBar-Color"), for: .tabBar).toolbarBackground(.visible, for: .tabBar)
	...
}

De esta forma no es necesario inicializar con UIKit.

¿Y la explicación?

En mi camino para convertirme en desarrollador nunca me ha gustado solamente copiar y pegar código sin entender el “por qué” entonces basado en mi experiencia intentare explicar que es lo que sucede en cada caso:

Solución 1:

En lo poco que llevo como desarrollador iOS, he notado que el toolbar parece no tener un color de fondo por defecto entonces al momento de que swift detecta que hay elementos “por detrás” este asigna un fondo blanco y transparente, lo que estaría sustituyendo nuestra configuración inicial

Al nosotros poner ese background como hidden evitamos que se muestre el fondo configurado por swiftui (ya que entiendo que podría arruinar la UX)

Solución 2:

Esta solución la encontré en un foro de StackOverflow así que te dejo un fragmento de la explicación:

El primer modificador establece el color del fondo. El segundo hace que el fondo sea visible en todo momento, independientemente del contenido de desplazamiento subyacente. Estos modificadores también se pueden utilizar de forma individual.

Reto

  • Agregué un padding de 25 arriba para los títulos
.padding(.top, 25)

Y la última sección “Videos que podrían gustarte”


Text("VIDEOS QUE PODRÍAN GUSTARTE")
                .font(.title3)
                .foregroundColor(.white)
                .bold()
                .frame(minWidth: 0, maxWidth: .infinity, alignment: .leading)
                .padding(.top, 25)
            ScrollView(.horizontal, showsIndicators: false)
            {
                HStack
                {
                    //
                    Button(action: {
                        url = urlVideos[4]
                        print("URL: \(url)")
                        isPlayerActive = true
                        
                    }, label: {
                        
                        
                            Image("lastofus").resizable()
                                .scaledToFit()
                                .frame(width: 240, height: 135)
                        
                        
                    })
                    
                    //
                    Button(action: {
                        url = urlVideos[5]
                        print("URL: \(url)")
                        isPlayerActive = true
                        
                    }, label: {
                        
                        
                            Image("destiny_complete").resizable()
                                .scaledToFit()
                                .frame(width: 240, height: 135)
                        
                        
                    })
                    
                    //
                    Button(action: {
                        url = urlVideos[6]
                        print("URL: \(url)")
                        isPlayerActive = true
                        
                    }, label: {
                        
                        
                            Image("spiderman").resizable()
                                .scaledToFit()
                                .frame(width: 240, height: 135)
                        
                        
                    })
                    
                    
                    
                }

Mi .navigationBarHidden(true) dejo de funcionar, al parecer es un bug de swiftUI.