[SwiftUI] UberClone: MapView

Junyoung Parkยท2022๋…„ 11์›” 18์ผ
0

SwiftUI

๋ชฉ๋ก ๋ณด๊ธฐ
111/136
post-thumbnail

๐Ÿ”ด Let's Build UBER with SwiftUI | iOS 16 & Xcode 14

UberClone: MapView

๊ตฌํ˜„ ๋ชฉํ‘œ

  • ์ปค์Šคํ…€ ๋งต๋ทฐ ๊ตฌํ˜„

๊ตฌํ˜„ ํƒœ์Šคํฌ

  • UIKit ์ปดํฌ๋„ŒํŠธ์˜ SwiftUI ๋‚ด ์‚ฌ์šฉ์„ ์œ„ํ•œ UIViewRepresentable
  • ํ™ˆ๋ทฐ ๋‚ด ์‚ฌ์šฉ๋˜๋Š” ๋กœ์ผ€์ด์…˜ ๋งค๋‹ˆ์ €

ํ•ต์‹ฌ ์ฝ”๋“œ

import Foundation
import CoreLocation

class LocationManager: NSObject, ObservableObject {
    private let locationManager = CLLocationManager()
    
    override init() {
        super.init()
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    }
}

extension LocationManager: CLLocationManagerDelegate {
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        guard !locations.isEmpty else { return }
        locationManager.stopUpdatingLocation()
    }
}
  • ๋งต๋ทฐ ๋‚ด์—์„œ ์‚ฌ์šฉ๋˜๋Š” ObservableObject๋กœ ์„ ์–ธ๋˜๋Š” ๋กœ์ผ€์ด์…˜ ๋งค๋‹ˆ์ €
  • CLLocationManagerDelegate ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ, ์œ ์ € ์ •๋ณด์— ๋”ฐ๋ผ ์ง€๋„๋ฅผ ์—…๋ฐ์ดํŠธํ•œ ๋’ค ์—…๋ฐ์ดํŠธ๋œ ์ดํ›„ ๊ณง๋ฐ”๋กœ ์—…๋ฐ์ดํŠธ ์ค‘์ง€
import SwiftUI
import MapKit

struct UberMapViewRepresentable: UIViewRepresentable {
    
    let mapView = MKMapView()
    let locationManager = LocationManager()
    
    func makeCoordinator() -> MapCoordinator {
        return MapCoordinator(parent: self)
    }
    
    func makeUIView(context: Context) -> some UIView {
        mapView.delegate = context.coordinator
        mapView.isRotateEnabled = false
        mapView.showsUserLocation = true
        mapView.userTrackingMode = .follow
        return mapView
    }
    
    func updateUIView(_ uiView: UIViewType, context: Context) {
    }
}
  • SwiftUI์—์„œ UIKit ์ปดํฌ๋„ŒํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ UIViewRepresentable์„ ์ค€์ˆ˜ํ•˜๋Š” ํด๋ž˜์Šค ์„ ์–ธ
  • ํ•ด๋‹น ํ”„๋กœํ† ์ฝœ์„ ๋”ฐ๋ฅด๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜ ์„ ์–ธ์„ ํ†ตํ•ด ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ์™€ ์กฐ์œจํ•˜๋Š” makeCoordinator, ์‚ฌ์šฉํ•  ์ปค์Šคํ…€ ๋ทฐ ํด๋ž˜์Šค๋ฅผ ๋˜์ง€๋Š” makeUIView ํ•จ์ˆ˜ ์ ์šฉ
  • ํด๋ž˜์Šค ๋‚ด ์ปค์Šคํ…€์œผ๋กœ ์„ ์–ธ๋˜๋Š” ๊ณณ(๋งต๋ทฐ, ๋กœ์ผ€์ด์…˜ ๋งค๋‹ˆ์ € ๋“ฑ)์„ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํ•จ์ˆ˜์—์„œ๋„ ์ ‘๊ทผ ๊ฐ€๋Šฅ
  • ์ฆ‰ ํ˜„์žฌ UIView ์ž…์žฅ์—์„œ๋Š” ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•˜๋Š” ํŠน์ •ํ•œ ๋ทฐ์˜ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํ•จ์ˆ˜๋Š” ์•Œ์ง€ ๋ชปํ•˜๊ณ , Coordinator์„ ๊ฒฝ์œ ํ•ด์„œ๋งŒ ์‚ฌ์šฉ ๊ฐ€๋Šฅ(ํ˜„์žฌ ๋งต๋ทฐ์˜ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ์— ์ปจํ…์ŠคํŠธ์˜ coordinator๋ฅผ ๋„˜๊ธฐ๊ธฐ ๋•Œ๋ฌธ)
extension UberMapViewRepresentable {
    class MapCoordinator: NSObject, MKMapViewDelegate {
        let parent: UberMapViewRepresentable
        
        init(parent: UberMapViewRepresentable) {
            self.parent = parent
            super.init()
        }
        
        func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
            let region = MKCoordinateRegion(center: .init(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude), span: .init(latitudeDelta: 0.05, longitudeDelta: 0.05))
            parent.mapView.setRegion(region, animated: true)
        }
    }
}
  • ์ปค์Šคํ…€ ๋ทฐ์—์„œ ์„ ์–ธ๋˜๋Š” Coordinator ํด๋ž˜์Šค
  • ์œ„์˜ ์ปค์Šคํ…€ ๋ทฐ๋ฅผ self๋กœ ์ฃผ๊ธฐ ๋•Œ๋ฌธ์— ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํ•จ์ˆ˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • ํ˜„์žฌ ์‚ฌ์šฉ ์ค‘์ธ ๋งตํ‚ท์˜ ๋ธ๋ฆฌ๊ฒŒ์ดํŠธ ํ•จ์ˆ˜๋Š” ์œ ์ € ์œ„์น˜ํ•œ ๊ฐ’์„ ํ†ตํ•ด ๋งต๋ทฐ์˜ ์ง€์—ญ์„ ์„ธํŒ…ํ•˜๋Š” ํ•จ์ˆ˜
import SwiftUI

struct HomeView: View {
    var body: some View {
        UberMapViewRepresentable()
            .ignoresSafeArea()
    }
}
  • ์œ„์˜ ๋งตํ‚ท ์ž์ฒด๋ฅผ ์ „์ฒด ์ง€๋„๋กœ ์˜ฌ๋ฆฌ๋Š” ์ฝ”๋“œ

๊ตฌํ˜„ ํ™”๋ฉด

profile
JUST DO IT

0๊ฐœ์˜ ๋Œ“๊ธ€