- Published on
SwiftUI Map App β Maxsus xarita pinlari (Map Annotations)
- Authors
- Name
- ShoxruxC
- @iOSdasturchi
Maxsus xarita pinlari β MapAnnotation
Bu videoda xaritaga joy belgilari (pinlar) qo'shiladi. Avval Apple-ning standart pinlari ishlatiladi, keyin ular maxsus LocationMapAnnotationView bilan almashtiriladi.
Map initializer-ini yangilash
Annotatsiyalarni qo'llash uchun Map komponentining yangi initializer-i ishlatiladi:
// Oldingi (annotatsiyasiz)
Map(coordinateRegion: $vm.mapRegion)
// Yangi (annotatsiyali)
Map(
coordinateRegion: $vm.mapRegion,
annotationItems: vm.locations
) { location in
// Har bir joy uchun pin
}
annotationItems β Identifiable protokoliga mos bo'lgan har qanday to'plam qabul qiladi. Location allaqachon Identifiable-ga mos, shuning uchun qo'shimcha o'zgarish kerak emas.
Standart pinlar β MapMarker
Tez sinab ko'rish uchun Apple-ning standart markeri:
Map(
coordinateRegion: $vm.mapRegion,
annotationItems: vm.locations
) { location in
MapMarker(coordinate: location.coordinates, tint: .blue)
}
Bu ishlaydi, lekin ilovaning umumiy uslubiga mos kelmaydi. Shuning uchun maxsus pin yaratiladi.
LocationMapAnnotationView β maxsus pin
Views/ papkasida yangi SwiftUI View β LocationMapAnnotationView.swift yaratiladi:
struct LocationMapAnnotationView: View {
let accentColor = Color("AccentColor")
var body: some View {
VStack(spacing: 0) {
// Asosiy doira icon
Image(systemName: "map.circle.fill")
.resizable()
.scaledToFit()
.frame(width: 30, height: 30)
.font(.headline)
.foregroundColor(.white)
.padding(6)
.background(accentColor)
.cornerRadius(36)
// Uchburchak β o'q ko'rinishida
Image(systemName: "triangle.fill")
.resizable()
.scaledToFit()
.foregroundColor(accentColor)
.frame(width: 10, height: 10)
.rotationEffect(Angle(degrees: 180))
.offset(y: -3)
.padding(.bottom, 40)
}
}
}
Muhim tafsilotlar:
.cornerRadius(36) β doira hosil qilish uchun: frame(30) + padding(6)*2 = 42 β cornerRadius(36) β yarmi β to'liq doira.
.padding(.bottom, 40) β xaritada pin-ning markaziy nuqtasi VStack-ning o'rtasi bo'ladi. Pastga 40pt padding qo'shish markazni pastga tushiradi, ya'ni pin tepasiga joylashadi β shu tariqa pin aniq joylashuv ustini emas, tepasini ko'rsatadi.
Preview uchun:
struct LocationMapAnnotationView_Previews: PreviewProvider {
static var previews: some View {
ZStack {
Color.black.ignoresSafeArea()
LocationMapAnnotationView()
}
}
}
Maxsus pini xaritaga qo'shish
Map(
coordinateRegion: $vm.mapRegion,
annotationItems: vm.locations
) { location in
MapAnnotation(coordinate: location.coordinates) {
LocationMapAnnotationView()
.shadow(radius: 10)
.scaleEffect(vm.mapLocation == location ? 1 : 0.7)
.onTapGesture {
vm.showNextLocation(location: location)
}
}
}
.scaleEffect β tanlangan pin katta (1.0), qolganlar kichik (0.7). Joy o'zgarganida animatsiya bilan o'lcham almashinadi.
.onTapGesture β pin bosilganda vm.showNextLocation(location:) chaqiriladi. Shu bilan menyu, preview karta, xarita va pin β barchasi bir vaqtda yangilanadi.
Body-ni tozalash
Xarita kodi va preview stack alohida computed property-larga ajratiladi:
struct LocationsView: View {
@EnvironmentObject private var vm: LocationsViewModel
var body: some View {
ZStack {
mapLayer
VStack(spacing: 0) {
header
.padding()
Spacer()
locationsPreviewStack
}
}
}
}
extension LocationsView {
private var mapLayer: some View {
Map(
coordinateRegion: $vm.mapRegion,
annotationItems: vm.locations
) { location in
MapAnnotation(coordinate: location.coordinates) {
LocationMapAnnotationView()
.shadow(radius: 10)
.scaleEffect(vm.mapLocation == location ? 1 : 0.7)
.onTapGesture {
vm.showNextLocation(location: location)
}
}
}
.ignoresSafeArea()
}
private var locationsPreviewStack: some View {
ZStack {
ForEach(vm.locations) { location in
if vm.mapLocation == location {
LocationPreviewView(location: location)
.shadow(color: .black.opacity(0.3), radius: 20)
.padding()
.transition(.asymmetric(
insertion: .move(edge: .trailing),
removal: .move(edge: .leading)
))
}
}
}
}
}
Endi body quyidagicha toza va o'qilishi oson:
var body: some View {
ZStack {
mapLayer // xarita
VStack(spacing: 0) {
header // yuqori menyu
Spacer()
locationsPreviewStack // pastki karta
}
}
}
MapMarker va MapAnnotation farqi
MapMarker | MapAnnotation | |
|---|---|---|
| Ko'rinish | Apple-ning standart pini | Istalgan SwiftUI view |
| Sozlash | Faqat tint rangi | To'liq erkin |
| iOS versiyasi | iOS 14+ | iOS 14+ |
| Ishlatish holati | Tez prototip | Maxsus dizayn |
Video oxiridagi yangiliklar
Views/
βββ LocationsView.swift
β βββ mapLayer β annotatsiyali Map
β βββ locationsPreviewStack β ajratilgan
βββ LocationMapAnnotationView.swift β yangi fayl
Keyingi videoda "Batafsil" tugmasi uchun LocationDetailView β rasmlar galereyasi, joy tavsifi va Wikipedia havolasi β quriladi.