Cloning Airbnb with SwiftUI
Hello to everyone arriving at the blog! It’s been a few days since my last post. I’ve been short on time while moving from Itaú to iFood, a new challenge. After just a few weeks, I can already tell this will be an exciting project with plenty of room to grow. With that said, let’s return to the side project, which hasn’t stopped! o/
Two weeks ago, I started recreating interfaces from major apps in SwiftUI. Airbnb was the first one I chose.
I thought I’d build the home screen easily and write about it the next day. I was wrong! I started by organizing the screen into stacks, as we do in SwiftUI:
// First card with big image
ScrollView {
VStack() {
Image("airbnb-home-cardPrincipal")
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: self.width, height: self.height)
}
.cornerRadius(borderRounded)
This was meant to look like the first card on Airbnb’s original home screen. It didn’t turn out as expected: I was working with a screenshot from the app and couldn’t get .cornerRadius(borderRounded) to round it properly. I moved on to the second part, a horizontally scrolling set of cards:
GeometryReader { bounds in
ScrollView(.horizontal, showsIndicators: false) {
HStack(spacing: 20) {
ForEach(homeData) { item in
GeometryReader { geometry in
Home(item)
.rotation3DEffect(Angle(degrees:
Double(geometry.frame(in: .global).minX - 30) / -getAngleMultiplier(bounds: bounds)
), axis: (x: 0, y: 10, z: 0))
}
.frame(width: 275, height: 275)
}
}
.padding(30)
.padding(.bottom, 30)
}
}
Then I ran into another obstacle. I was creating an array to populate ForEach, but the loop didn’t seem to run, and I also got initialization errors:
struct Home: Identifiable {
var id = UUID()
var image: Image
var color: Color
}
let homeData = [
Home(text: "Online Experiences", image: Image(uiImage: #imageLiteral(resourceName: "airbnb-home-card1")), color: Color(#colorLiteral(red: 0.2196078449, green: 0.007843137719, blue: 0.8549019694, alpha: 1))),
Home(text: "Unique stays", image: Image(uiImage: #imageLiteral(resourceName: "airbnb-home-card2")), color: Color(#colorLiteral(red: 0.2196078449, green: 0.007843137719, blue: 0.8549019694, alpha: 1))),
Home(text: "Entire homes", image: Image(uiImage: #imageLiteral(resourceName: "airbnb-home-card3")), color: Color(#colorLiteral(red: 0.2196078449, green: 0.007843137719, blue: 0.8549019694, alpha: 1)))
]
The problem here is that Home isn’t initialized, so it can’t iterate through the array. :(
I hesitated to share this less-than-pleasant SwiftUI experience, but it was a useful lesson in structuring a view. A screen that seems simple requires a new way of thinking, and I’m still learning it.
If you have suggestions for improving these first two sections, feel free to send a PR or comment on the GitHub project. I’ll be back in two weeks to continue the story and see whether I’ve solved these issues.
See you soon!