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.