Published on

SwiftUI Map App β€” MapKit bilan xarita qo'shish

Authors

MapKit bilan xarita qo'shish

Bu videoda ilovaga birinchi xarita qo'shiladi va xarita holati ViewModel-ga ko'chiriladi β€” shu tariqa xaritani dastur ichidan boshqarish mumkin bo'ladi.


MapKit import qilish

SwiftUI-ning Map komponenti MapKit kutubxonasida joylashgan. LocationsView.swift faylining boshiga import qo'shiladi:

import SwiftUI
import MapKit

Xaritani ZStack-ga qo'shish

Mavjud ro'yxat o'chiriladi. Uning o'rniga ZStack ichiga Map joylashtiriladi:

struct LocationsView: View {

    @EnvironmentObject private var vm: LocationsViewModel

    var body: some View {
        ZStack {
            Map(coordinateRegion: $vm.mapRegion)
                .ignoresSafeArea()
        }
    }
}

.ignoresSafeArea() β€” xarita ekranning barcha chetlarigacha cho'zilishi uchun.


MKCoordinateRegion β€” xarita hududi

Map komponenti koordinata regioniga bog'lanadi. Region ikki qismdan iborat:

  • center β€” xaritaning markaziy nuqtasi (CLLocationCoordinate2D)
  • span β€” qanchalik kattalashtirish (kichik qiymat = ko'proq zoom)
MKCoordinateRegion(
    center: CLLocationCoordinate2D(latitude: 41.8902, longitude: 12.4922),
    span: MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)
)

latitudeDelta va longitudeDelta = 0.1 β€” shahar darajasida zoom.


Xarita regionini ViewModel-ga ko'chirish

Xarita regionini view ichida saqlash o'rniga, uni ViewModel-da saqlash kerak β€” bu ViewModel orqali xaritani dasturiy boshqarish imkonini beradi.

LocationsViewModel yangilangan versiyasi

import Foundation
import MapKit

class LocationsViewModel: ObservableObject {

    // Barcha yuklanΠ³Π°Π½ joylar
    @Published var locations: [Location] = []

    // Xaritada hozir ko'rsatilayotgan joy
    @Published var mapLocation: Location {
        didSet {
            updateMapRegion(location: mapLocation)
        }
    }

    // Xaritaning joriy hududi
    @Published var mapRegion: MKCoordinateRegion = MKCoordinateRegion()

    // Zoom darajasi
    let mapSpan = MKCoordinateSpan(latitudeDelta: 0.1, longitudeDelta: 0.1)

    init() {
        let locations = LocationsDataService.locations
        self.locations = locations
        self.mapLocation = locations.first!
        self.updateMapRegion(location: locations.first!)
    }

    private func updateMapRegion(location: Location) {
        withAnimation(.easeInOut) {
            mapRegion = MKCoordinateRegion(
                center: location.coordinates,
                span: mapSpan
            )
        }
    }
}

Muhim tafsilotlar

didSet β€” mapLocation o'zgarganda updateMapRegion() avtomatik chaqiriladi. Bu ikkita o'zgaruvchini qo'lda yangilash zarurligini yo'qotadi: faqat mapLocation o'zgartirilsa, mapRegion o'zi yangilanadi.

locations.first! β€” bu explicit unwrap (majburiy o'chirish) xavfli ko'rinishi mumkin. Lekin bu holda LocationsDataService.locations doim kamida bitta elementga ega ekanligini bilganimiz uchun qabul qilinadi. Agar ma'lumotlar tarmoqdan yuklanayotgan bo'lsa, bu yondashuv ishlatilmaydi.

withAnimation(.easeInOut) β€” joy o'zgarganida xarita silliq animatsiya bilan yangi joylashuvga ko'chadi.


LocationsView β€” yakuniy versiya

import SwiftUI
import MapKit

struct LocationsView: View {

    @EnvironmentObject private var vm: LocationsViewModel

    var body: some View {
        ZStack {
            Map(coordinateRegion: $vm.mapRegion)
                .ignoresSafeArea()
        }
    }
}

struct LocationsView_Previews: PreviewProvider {
    static var previews: some View {
        LocationsView()
            .environmentObject(LocationsViewModel())
    }
}

Ma'lumot oqimi

LocationsDataService.locations
        ↓
LocationsViewModel.init()
        ↓
mapLocation = locations.first!
        ↓ (didSet ishga tushadi)
updateMapRegion(location:)
        ↓
mapRegion yangilanadi
        ↓
Map(coordinateRegion: $vm.mapRegion)
        ↓
Xarita ekranda ko'rinadi

Keyinchalik foydalanuvchi joy tanlasa, faqat vm.mapLocation = newLocation deb yozish yetarli β€” xarita o'zi animatsiya bilan yangi joyga ko'chadi.


Video oxiridagi loyiha holati

ViewModels/
└── LocationsViewModel.swift
    β”œβ”€β”€ locations: [Location]       ← barcha joylar
    β”œβ”€β”€ mapLocation: Location       ← tanlangan joy (didSet bilan)
    β”œβ”€β”€ mapRegion: MKCoordinateRegion ← xarita hududi
    β”œβ”€β”€ mapSpan                     ← zoom darajasi
    └── updateMapRegion(location:)  ← private funksiya

Views/
└── LocationsView.swift
    └── Map(coordinateRegion: $vm.mapRegion)

Keyingi videoda xaritaga maxsus pinlar qo'shiladi va joy tanlash logikasi quriladi.

Buy mea coffee