π΄ Let's Build UBER with SwiftUI | iOS 16 & Xcode 14
UberClone: Location Search UI
ꡬν λͺ©ν
- μμΉ κ²μ λ·° UI ꡬν
ꡬν νμ€ν¬
- μμΉ κ²μ κ²°κ³Ό μ¬μ¬μ© μ
ꡬν
- λ²νΌ ν κΈ μ‘μ
ꡬν
ν΅μ¬ μ½λ
import SwiftUI
struct LocationSearchActivationView: View {
var body: some View {
HStack {
Rectangle()
.fill(Color(.black))
.frame(width: 8, height: 8)
.padding(.horizontal)
Text("Where to?")
.foregroundColor(Color(.darkGray))
Spacer()
}
.frame(width: UIScreen.main.bounds.width - 64, height: 50)
.background(
Rectangle()
.fill(Color(.white))
.shadow(color: .black, radius: 6)
)
}
}
- μ§μ κ²μ μ°½μ λμ°κΈ° μ μ¬μ©μμκ² μ§λ¬Έμ λμ§λ λ·°
import SwiftUI
struct LocationSearchView: View {
@State private var startLocationText = ""
@State private var destinationLocationText = ""
var body: some View {
VStack {
HStack {
VStack {
Circle()
.fill(Color(.systemGray3))
.frame(width: 6, height: 6)
Rectangle()
.fill(Color(.systemGray3))
.frame(width: 1, height: 24)
Rectangle()
.fill(.black)
.frame(width: 6, height: 6)
}
VStack {
TextField("Current Location", text: $startLocationText, axis: .vertical)
.frame(minHeight: 32)
.background(Color(.systemGroupedBackground))
.padding(.trailing)
TextField("Where to?", text: $destinationLocationText, axis: .vertical)
.frame(minHeight: 32)
.background(Color(.systemGray4))
.padding(.trailing)
}
}
.padding(.horizontal)
.padding(.top, 64)
Divider()
.padding(.vertical)
ScrollView {
VStack(alignment: .leading) {
ForEach(0..<20, id: \.self) { _ in
LocationSearchResultCell()
}
}
}
}
.background(Color.white)
}
}
- μΆλ°μ§μ λμ°©μ§ ν
μ€νΈ μ
λ ₯μ λ°λΌ νλ¨λΆμ 쿼리 κ²°κ³Όμ λ°λ₯Έ μ
μ 리μ€νΈ νμμΌλ‘ λμ°λ λ·°
import SwiftUI
struct LocationSearchResultCell: View {
var body: some View {
HStack {
Image(systemName: "mappin.circle.fill")
.resizable()
.foregroundColor(.blue)
.tint(.white)
.frame(width: 40, height: 40)
VStack(alignment: .leading, spacing: 4) {
Text("Starbucks Coffee")
.font(.body)
Text("123 Main St, Cupertino CA")
.font(.callout)
.foregroundColor(.gray)
Divider()
}
.padding(.leading, 8)
.padding(.vertical, 8)
}
.padding(.leading)
}
}
- 맡 λ·° μ’μΈ‘ μλ¨ λΆμ νλ‘ν
νμμΌλ‘ ꡬνλμ΄ μλ ν κΈ λ²νΌ
- λ²νΌ ν΄λ¦ μ 맡 λ·° - μ§μ κ²μ 리μ€νΈ λ·° μ ν κ°λ₯
import SwiftUI
struct HomeView: View {
@State private var showLocationSearchView: Bool = false
var body: some View {
ZStack(alignment: .top) {
UberMapViewRepresentable()
.ignoresSafeArea()
if showLocationSearchView {
LocationSearchView()
} else {
LocationSearchActivationView()
.padding(.top, 72)
.onTapGesture {
withAnimation(.spring()) {
showLocationSearchView.toggle()
}
}
}
MapViewActionButton(showLocationSearchView: $showLocationSearchView)
.padding(.leading)
.padding(.top, 4)
}
}
}
showLocationSearchView
λΆλ¦¬μΈ νλ‘νΌν°λ₯Ό 맡 λ·° λ²νΌμ λ°μΈλ©μΌλ‘ λκΉμΌλ‘μ¨ ν΄λΉ κ° λ³ν κ°λ₯
- ν
μ€νΈ λ°μ€ ν΄λ¦ λν ν΄λΉ νλ‘νΌν°λ₯Ό λ³κ²½ κ°λ₯
import SwiftUI
struct MapViewActionButton: View {
@Binding var showLocationSearchView: Bool
var body: some View {
Button {
withAnimation(.spring()) {
showLocationSearchView.toggle()
}
} label: {
Image(systemName: showLocationSearchView ? "arrow.left" : "line.3.horizontal")
.font(.title2)
.foregroundColor(.black)
.padding()
.background(.white)
.clipShape(Circle())
.shadow(color: .black, radius: 6)
}
.frame(maxWidth: .infinity, alignment: .leading)
}
}
- λ°μΈλ©μΌλ‘ λ겨 λ°μ κ°μ μ λλ©μ΄μ
κ³Ό ν¨κ» μ ννλ λ²νΌ
ꡬν νλ©΄