[SwiftUI] UberClone: Location Search UI

Junyoung ParkΒ·2022λ…„ 11μ›” 19일
0

SwiftUI

λͺ©λ‘ 보기
112/136
post-thumbnail
post-custom-banner

πŸ”΄ 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 {
            // header view
            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)

            // list view
            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)

    }
}
  • λ°”μΈλ”©μœΌλ‘œ λ„˜κ²¨ 받은 값을 μ• λ‹ˆλ©”μ΄μ…˜κ³Ό ν•¨κ»˜ μ „ν™˜ν•˜λŠ” λ²„νŠΌ

κ΅¬ν˜„ ν™”λ©΄

μ—…λ‘œλ“œμ€‘..

profile
JUST DO IT
post-custom-banner

0개의 λŒ“κΈ€