Vinicius Carvalho

Vinicius Carvalho

iOS Engineer. Developer and more.

© 2024

Dark Mode

Clone do Aibnb em SwiftUI - Parte 2

Passei muito tempo sem aparecer por aqui não é? Confesso que é um pouco difícil conciliar trabalho, vida e produzir conteúdo, tem que conseguir equilibrar tudo isso. Voltamos com uma abordagem dois para o desafio de recriar o design do app do Aibnb.

Primeiro de tudo, refiz todo o esquema de pastas porque isso era uma das coisas que mais me deixava perdido em projetos de SwiftUI que tudo era jogado na mesma pasta. Refiz e coloquei dessa maneira abaixo,

airbnb-home
 |___Model
 |___Views
  |_____Cells
  |_____Sections
 |___Navigation
 |___Screens

Os benefícios foram nítidos logo de cara pois consegui identificar cada elemento da tela mais facilmente, pois dividi por cells e sections

Vamos dividir por área então, começando com a foto principal,

ZStack(alignment: .top) {
            ScrollView {
                VStack {
                    HStack {
                        Spacer()
                        Image("airbnb-home-cardPrincipal")
                            .resizable()
                            .cornerRadius(6)
                            .frame(width: 315, height: 400)
                            .foregroundColor(.white)
                    }
                }
                .padding(16)
                .padding(.trailing, 16)
                .padding(.leading, 16)

O primeiro ponto que devemos abordar aqui é que como eu não tinha as fotos de qualidade eu acabei tirando print das que tem no app para tentar reproduzir, se você compilar o app que vou deixar aqui no final do artigo o link, vai perceber que tem um padding maior do lado esquerdo e não sei o porquê! -.-‘

Depois criei a Section que ia conter a view com scroll horizontal com as fotos.

struct ExperiencesSectionView: View {
    var body: some View {
        ScrollView(.horizontal, showsIndicators: false) {
            HStack(spacing: 12) {
                ForEach(GenericContent.experiencesData) { item in
                    ExperiencesCell(data: item)
                }
            }
            .padding()
            .padding(.top, -16)
        }
    }
}

Veja que aqui eu só estou fazendo um ForEach nas minhas células de ExperiencesCell assim fica mais fácil pra poder encapsular e não deixar aquele código inteiro na HomeView, como estava antes.

Já na minha célula,

struct ExperiencesCell: View {
    var data: GenericContent
    var body: some View {
        VStack(alignment: .leading) {
            Image(data.imageName)
                .resizable()
                .cornerRadius(4)
                .frame(width: 180, height: 130)
            Text(data.title)
                .foregroundColor(.black)
                .fontWeight(.semibold)
                .font(.subheadline)
            HStack {
                Text(data.subtitle ?? "")
                    .foregroundColor(.black)
                    .font(.system(size: 14, weight: .light))
                    .frame(width: 160, alignment: .leading)
            }
        }
    }
}

Aqui fica bonitinho também o título e o subtítulo, mas tem um ponto que queria levantar é que ele não está com a aparência de card sabe? Como se tivesse encapsulado tudo no mesmo segmento. Tenho que pesquisar mais afundo como fazer isso e tento trazer isso aqui no próximo artigo.

Por fim para finalizar essa reformulação criei uma outra Section que é uma área com o background preto no app. Resolvi criar o título usando o SectionTitle e o subtítulo eu passo direto na view mesmo, assim como o botão que criei. Aliás, deixei o ForEach comentado pois vou receber outro esquema de células que tem o scroll horizontal, mas ainda não completei essa célula.

Ah, também adicionei uma Tab, mas como não tenho os ícones, vou tentar colocar alguns default mesmo para não deixar o espaço em branco.

Para apresentar tudo isso que criei ficou mais fácil, pois antes jogava praticamente toda a criação na View principal,

var body: some View {
        ZStack(alignment: .top) {
            ScrollView {
                VStack {
                    HStack {
                        Spacer()
                        Image("airbnb-home-cardPrincipal")
                            .resizable()
                            .cornerRadius(6)
                            .frame(width: 315, height: 400)
                            .foregroundColor(.white)
                    }
                }
                .padding(16)
                .padding(.trailing, 16)
                .padding(.leading, 16)
                
                ExperiencesSectionView()
                SectionTitle(title: "Online Experiences: Field Tips")
                OnlineExperiencesSectionView()
            }
            .padding(.bottom, 30)
        }
        
    }
}

Eu só chamo na ordem de que vai apresentar na tela os elementos, dessa forma eu consigo rearranjar até o modo de apresentação de cada um, foi tirado a responsabilidade de criação da Home e ela cuida só de apresentar e qual a sequência, bem mais fácil!

Foi isso, se você quer acompanhar essa saga e briga de recriar a interface visual do app do Airbnb acompanhe os commits nesse repositório, PRs são bem vindos e se quiser opinar ou tirar dúvidas de como to criando, só criar issues lá ou falar comigo no Twitter :)

Até mais.