1. Başlamadan Önce
Bu codelab'de, iOS için Haritalar SDK'sını SwiftUI ile nasıl kullanacağınız açıklanmaktadır.
Ön koşullar
- Temel Swift bilgisi
- SwiftUI ile ilgili temel bilgiler
Yapacaklarınız
- SwiftUI kullanarak bir iOS uygulamasına Google Haritalar eklemek için iOS için Haritalar SDK'sını etkinleştirin ve kullanın.
- Haritaya işaretçi ekleyin.
- SwiftUI ile
GMSMapView
nesnesi arasında durumu aktarma.
İhtiyacınız olanlar
- Xcode 11.0 veya sonraki sürümler
- Faturalandırmanın etkinleştirildiği bir Google Hesabı
- iOS için Haritalar SDK'sı
- Kartaca
2. Hazırlanın
Aşağıdaki etkinleştirme adımı için iOS için Haritalar SDK'sını etkinleştirin.
Google Haritalar Platformu'nu ayarlama
Henüz bir Google Cloud Platform hesabınız ve faturalandırmanın etkinleştirildiği bir projeniz yoksa lütfen faturalandırma hesabı ve proje oluşturmak için Google Haritalar Platformu'nu Kullanmaya Başlama kılavuzuna bakın.
- Cloud Console'da proje açılır menüsünü tıklayın ve bu codelab için kullanmak istediğiniz projeyi seçin.
- Bu codelab için gereken Google Haritalar Platformu API'lerini ve SDK'larını Google Cloud Marketplace'te etkinleştirin. Bunun için bu videodaki veya bu dokümandaki adımları uygulayın.
- Cloud Console'un Kimlik Bilgileri sayfasında bir API anahtarı oluşturun. Bu videodaki veya bu dokümandaki adımları uygulayabilirsiniz. Google Haritalar Platformu'na yapılan tüm istekler için API anahtarı gerekir.
3. Başlangıç kodunu indirme
Mümkün olduğunca hızlı bir şekilde başlamanıza yardımcı olmak için bu codelab'i takip etmenize yardımcı olacak başlangıç kodunu aşağıda bulabilirsiniz. Çözüme geçebilirsiniz ancak kendiniz oluşturmak için tüm adımları takip etmek istiyorsanız okumaya devam edin.
git
yüklüyse depoyu klonlayın.
git clone https://github.com/googlecodelabs/maps-ios-swiftui.git
Alternatif olarak, kaynak kodunu indirmek için aşağıdaki düğmeyi tıklayabilirsiniz.
- Kodu aldıktan sonra bir terminalde
cd
komutunu kullanarakstarter/GoogleMapsSwiftUI
dizinine gidin. - iOS için Haritalar SDK'sını indirmek üzere
carthage update --platform iOS
komutunu çalıştırın. - Son olarak,
GoogleMapsSwiftUI.xcodeproj
dosyasını Xcode'da açın.
4. Koda Genel Bakış
İndirdiğiniz başlangıç projesinde aşağıdaki sınıflar sizin için sağlanmış ve uygulanmıştır:
AppDelegate
- the application'sUIApplicationDelegate
. iOS için Haritalar SDK'sının başlatılacağı yer burasıdır.City
- Bir şehri temsil eden yapı (şehrin adını ve koordinatını içerir).- Google Harita (GMSMapView) içeren
MapViewController
- kapsamı daraltılmış bir UIKitUIViewController
SceneDelegate
:ContentView
öğesinin oluşturulduğu uygulamanınUIWindowSceneDelegate
.
Ayrıca, aşağıdaki sınıflar kısmen uygulanmıştır ve bu codelab'in sonunda sizin tarafınızdan tamamlanacaktır:
ContentView
- Uygulamanızı içeren üst düzey SwiftUI görünümü.MapViewControllerBridge
- UIKit görünümünü SwiftUI görünümüne bağlayan bir sınıf. Bu sınıf, SwiftUI'daMapViewController
erişilebilirliğini sağlar.
5. SwiftUI ve UIKit karşılaştırması
SwiftUI, iOS uygulamaları geliştirmek için iOS 13'te UIKit'e alternatif bir kullanıcı arayüzü çerçevesi olarak tanıtıldı. Önceki sürümü UIKit'e kıyasla SwiftUI'ın çeşitli avantajları vardır. Örneğin:
- Durum değiştiğinde görünümler otomatik olarak güncellenir. State adı verilen nesneler kullanıldığında, içerdiği temel değerde yapılan herhangi bir değişiklik kullanıcı arayüzünün otomatik olarak güncellenmesine neden olur.
- Canlı önizlemeler sayesinde daha hızlı geliştirme yapabilirsiniz. Canlı önizlemeler, SwiftUI görünümünün önizlemesi Xcode'da kolayca görülebildiğinden görsel değişiklikleri görmek için kodu oluşturup bir emülatöre dağıtma ihtiyacını en aza indirir.
- Doğru kaynağı Swift'te bulabilirsiniz. SwiftUI'daki tüm görünümler Swift'te bildirildiğinden artık Interface Builder'ı kullanmak gerekmez.
- UIKit ile birlikte çalışır. UIKit ile birlikte çalışabilirlik, mevcut uygulamaların mevcut görünümleriyle birlikte kademeli olarak SwiftUI kullanabilmesini sağlar. Ayrıca, iOS için Haritalar SDK'sı gibi henüz SwiftUI'ı desteklemeyen kitaplıklar da SwiftUI'da kullanılabilir.
Ancak bazı dezavantajları da vardır:
- SwiftUI yalnızca iOS 13 veya sonraki sürümlerde kullanılabilir.
- Görünüm hiyerarşisi, Xcode önizlemelerinde incelenemez.
SwiftUI State and data flow
SwiftUI, bildirim temelli bir yaklaşım kullanarak kullanıcı arayüzü oluşturmak için yeni bir yol sunar. SwiftUI'a görünümünüzün nasıl görünmesini istediğinizi ve tüm farklı durumlarını söylersiniz, sistem de gerisini halleder. SwiftUI, temel durum bir etkinlik veya kullanıcı işlemi nedeniyle her değiştiğinde görünümü günceller. Bu tasarım genellikle tek yönlü veri akışı olarak adlandırılır. Bu tasarımın ayrıntıları bu codelab'in kapsamı dışında olsa da Apple'ın Durum ve Veri Akışı dokümanında bu tasarımın işleyiş şekli hakkında bilgi edinmenizi öneririz.
UIViewRepresentable veya UIViewControllerRepresentable kullanarak UIKit ve SwiftUI'yi köprüleme
iOS için Haritalar SDK'sı UIKit üzerine kurulu olduğundan ve SwiftUI ile uyumlu bir görünüm sağlamadığından, SwiftUI'da kullanmak için UIViewRepresentable
veya UIViewControllerRepresentable
'ye uymanız gerekir. Bu protokoller, SwiftUI'ın sırasıyla UIKit ile oluşturulmuş UIView
ve UIViewController
öğelerini içermesini sağlar. SwiftUI görünümüne Google Haritası eklemek için iki protokolü de kullanabilirsiniz. Ancak bir sonraki adımda, harita içeren bir UIViewController
eklemek için UIViewControllerRepresentable
kullanmayı inceleyeceğiz.
6. Harita ekleme
Bu bölümde, Google Haritalar'ı bir SwiftUI görünümüne ekleyeceksiniz.
API anahtarınızı ekleme
Hesabınızı uygulamada gösterilecek haritayla ilişkilendirmek için önceki bir adımda oluşturduğunuz API anahtarının iOS için Haritalar SDK'sına sağlanması gerekir.
API anahtarınızı sağlamak için AppDelegate.swift
dosyasını açın ve application(_, didFinishLaunchingWithOptions)
yöntemine gidin. SDK, "YOUR_API_KEY" dizesiyle GMSServices.provideAPIKey()
kullanılarak başlatılır. Bu dizeyi API anahtarınızla değiştirin. Bu adımı tamamladığınızda uygulama başlatılırken iOS için Haritalar SDK'sı başlatılır.
MapViewControllerBridge kullanarak Google Haritası ekleme
API anahtarınız SDK'ya sağlandığına göre, bir sonraki adım haritayı uygulamada göstermektir.
Başlangıç kodunda sağlanan görünüm denetleyicisi MapViewController
, görünümünde GMSMapView
içerir. Ancak bu görünüm denetleyicisi UIKit'te oluşturulduğundan, ContentView
içinde kullanılabilmesi için bu sınıfı SwiftUI'ye köprülemeniz gerekir. Bunu yapmak için:
- Dosyayı
MapViewControllerBridge
Xcode'da açın.
Bu sınıf, bir UIKit UIViewController
öğesini sarmalayarak SwiftUI görünümü olarak kullanılabilmesi için gereken UIViewControllerRepresentable protokolüne uygundur. Başka bir deyişle, bu protokole uymak bir UIKit görünümünü SwiftUI görünümüne bağlamayı kolaylaştırır. Bu protokole uymak için iki yöntemin uygulanması gerekir:
makeUIViewController(context)
- Bu yöntem, temelUIViewController
öğesini oluşturmak için SwiftUI tarafından çağrılır.UIViewController
öğenizi burada oluşturur ve ilk durumunu iletirsiniz.updateUIViewController(_, context)
: Bu yöntem, durum her değiştiğinde SwiftUI tarafından çağrılır. Durum değişikliğine yanıt vermek için temelUIViewController
üzerinde değişiklik yapmanız gerekir.
MapViewController
oluşturun
makeUIViewController(context)
işlevinin içinde yeni bir MapViewController
oluşturun ve bunu sonuç olarak döndürün. Bu işlemi yaptıktan sonra MapViewControllerBridge
şu şekilde görünmelidir:
MapViewControllerBridge
import GoogleMaps
import SwiftUI
struct MapViewControllerBridge: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> MapViewController {
return MapViewController()
}
func updateUIViewController(_ uiViewController: MapViewController, context: Context) {
}
}
ContentView'da MapViewControllerBridge'i kullanma
MapViewControllerBridge
, MapViewController
örneğini oluşturduğuna göre bir sonraki adım, harita görüntülemek için bu yapıyı ContentView
içinde kullanmaktır.
- Dosyayı
ContentView
Xcode'da açın.
ContentView
, SceneDelegate
içinde oluşturulur ve üst düzey uygulama görünümünü içerir. Harita bu dosyanın içinden eklenir.
body
mülkünde birMapViewControllerBridge
oluşturun.
Bu dosyanın body
özelliği kapsamında sizin için ZStack
sağlanmış ve uygulanmıştır. ZStack
, sonraki bir adımda kullanacağınız, etkileşimli ve sürüklenebilir bir şehir listesi içerir. Şimdilik, şehir listesi görünümünün arkasında uygulamada bir harita gösterilmesi için ZStack
öğesinin ilk alt görünümü olarak MapViewControllerBridge
oluşturun.ZStack
Bu işlemden sonra ContentView
içindeki body
özelliğinin içeriği şu şekilde görünmelidir:
ContentView
var body: some View {
let scrollViewHeight: CGFloat = 80
GeometryReader { geometry in
ZStack(alignment: .top) {
// Map
MapViewControllerBridge()
// Cities List
CitiesList(markers: $markers) { (marker) in
guard self.selectedMarker != marker else { return }
self.selectedMarker = marker
self.zoomInCenter = false
self.expandList = false
} handleAction: {
self.expandList.toggle()
} // ...
}
}
}
- Şimdi uygulamayı çalıştırın. Haritanın cihazınızın ekranında yüklendiğini ve ekranın alt kısmında şehirlerin bulunduğu, sürüklenebilir bir liste göreceksiniz.
7. Haritaya işaretçi ekleme
Önceki adımda, şehir listesini gösteren etkileşimli bir listenin yanına harita eklediniz. Bu bölümde, listedeki her şehir için işaretçi ekleyeceksiniz.
Durum olarak işaretçiler
ContentView
, markers
adlı bir özellik bildirir. Bu özellik, cities
statik özelliğinde bildirilen her şehri temsil eden GMSMarker
listesidir. Bu özelliğin, SwiftUI tarafından yönetilmesi gerektiğini belirtmek için SwiftUI özellik sarmalayıcısı State ile açıklama eklenmiş olduğunu unutmayın. Bu nedenle, bu mülkte herhangi bir değişiklik algılanırsa (ör. işaretçi ekleme veya kaldırma) bu durumu kullanan görünümler güncellenir.
ContentView
static let cities = [
City(name: "San Francisco", coordinate: CLLocationCoordinate2D(latitude: 37.7576, longitude: -122.4194)),
City(name: "Seattle", coordinate: CLLocationCoordinate2D(latitude: 47.6131742, longitude: -122.4824903)),
City(name: "Singapore", coordinate: CLLocationCoordinate2D(latitude: 1.3440852, longitude: 103.6836164)),
City(name: "Sydney", coordinate: CLLocationCoordinate2D(latitude: -33.8473552, longitude: 150.6511076)),
City(name: "Tokyo", coordinate: CLLocationCoordinate2D(latitude: 35.6684411, longitude: 139.6004407))
]
/// State for markers displayed on the map for each city in `cities`
@State var markers: [GMSMarker] = cities.map {
let marker = GMSMarker(position: $0.coordinate)
marker.title = $0.name
return marker
}
ContentView
, şehir listesini oluşturmak için markers
özelliğini CitiesList
sınıfına ileterek kullandığını unutmayın.
CitiesList
struct CitiesList: View {
@Binding var markers: [GMSMarker]
var body: some View {
GeometryReader { geometry in
VStack(spacing: 0) {
// ...
// List of Cities
List {
ForEach(0..<self.markers.count) { id in
let marker = self.markers[id]
Button(action: {
buttonAction(marker)
}) {
Text(marker.title ?? "")
}
}
}.frame(maxWidth: .infinity)
}
}
}
}
@Binding
kullanarak durumu MapViewControllerBridge'e aktarın.
markers
özelliğinden gelen verileri gösteren şehir listesine ek olarak, bu özelliği MapViewControllerBridge
yapısına iletin. Böylece bu özellik, işaretçileri haritada göstermek için kullanılabilir. Bunu yapmak için:
MapViewControllerBridge
içinde@Binding
ile ek açıklama eklenmiş yeni birmarkers
özelliği bildirin.
MapViewControllerBridge
struct MapViewControllerBridge: : UIViewControllerRepresentable {
@Binding var markers: [GMSMarker]
// ...
}
MapViewControllerBridge
içinde,markers
özelliğini kullanmak içinupdateUIViewController(_, context)
yöntemini güncelleyin.
Önceki adımda belirtildiği gibi, durum her değiştiğinde SwiftUI tarafından updateUIViewController(_, context)
çağrılır. Haritayı bu yöntemle güncellemek ve işaretçileri markers
içinde göstermek istiyoruz. Bunu yapmak için her işaretçinin map
özelliğini güncellemeniz gerekir. Bu adımı tamamladıktan sonra MapViewControllerBridge
aşağıdaki gibi görünmelidir:
import GoogleMaps
import SwiftUI
struct MapViewControllerBridge: UIViewControllerRepresentable {
@Binding var markers: [GMSMarker]
func makeUIViewController(context: Context) -> MapViewController {
return MapViewController()
}
func updateUIViewController(_ uiViewController: MapViewController, context: Context) {
// Update the map for each marker
markers.forEach { $0.map = uiViewController.map }
}
}
markers
özelliğiniContentView
öğesindenMapViewControllerBridge
öğesine iletme
MapViewControllerBridge
içinde yeni bir özellik eklediğiniz için artık bu özelliğin değerinin MapViewControllerBridge
başlatıcısında iletilmesi gerekiyor. Bu nedenle, uygulamayı oluşturmaya çalıştığınızda derlenmediğini fark edersiniz. Bu sorunu düzeltmek için MapViewControllerBridge
öğesinin oluşturulduğu ContentView
bölümünde bir güncelleme yapın ve markers
özelliğini şu şekilde iletin:
struct ContentView: View {
// ...
var body: some View {
// ...
GeometryReader { geometry in
ZStack(alignment: .top) {
// Map
MapViewControllerBridge(markers: $markers)
// ...
}
}
}
}
MapViewControllerBridge
, bağlı bir özellik beklediğinden markers
değerini iletmek için $
önekini kullandığımıza dikkat edin. $
, Swift özellik sarmalayıcılarıyla kullanılmak üzere ayrılmış bir önek. Bir duruma uygulandığında Binding döndürür.
- Haritada gösterilen işaretçileri görmek için uygulamayı çalıştırın.
8. Animasyonu seçili bir şehre kadar oynatma
Önceki adımda, bir SwiftUI görünümünden diğerine State aktararak haritaya işaretçiler eklediniz. Bu adımda, etkileşimli listede dokunulduktan sonra bir şehri veya işaretçiyi canlandıracaksınız. Animasyonu gerçekleştirmek için, değişiklik meydana geldiğinde haritanın kamera konumunu değiştirerek bir durumdaki değişikliklere tepki verirsiniz. Haritanın kamerası kavramı hakkında daha fazla bilgi edinmek için Kamera ve Görünüm başlıklı makaleyi inceleyin.
Haritayı seçili şehre göre animasyonla hareket ettirme
Haritayı seçili bir şehre göre animasyonla göstermek için:
MapViewControllerBridge
içinde yeni bir bağlama tanımlayın
ContentView
, nil olarak başlatılan ve listede bir şehir seçildiğinde güncellenen selectedMarker
adlı bir State özelliğine sahiptir. Bu, ContentView
içindeki CitiesList
görünümü buttonAction
tarafından işlenir.
ContentView
CitiesList(markers: $markers) { (marker) in
guard self.selectedMarker != marker else { return }
self.selectedMarker = marker
// ...
}
selectedMarker
her değiştiğinde MapViewControllerBridge
, haritayı seçili işaretçiye göre canlandırabilmek için bu durum değişikliğinden haberdar olmalıdır. Bu nedenle, MapViewControllerBridge
içinde GMSMarker
türünde yeni bir Bağlama tanımlayın ve özelliğe selectedMarker
adını verin.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
@Binding var selectedMarker: GMSMarker?
}
selectedMarker
değiştiğinde haritayı animasyonlu hale getirmek içinMapViewControllerBridge
öğesini güncelleyin.
Yeni bir Bağlama bildirildikten sonra, haritanın seçilen işaretçiye göre animasyon oluşturması için MapViewControllerBridge
'nın updateUIViewController_, context)
işlevini güncellemeniz gerekir. Aşağıdaki kodu kopyalayarak bu işlemi yapabilirsiniz:
struct MapViewControllerBridge: UIViewControllerRepresentable {
@Binding var selectedMarker: GMSMarker?
func updateUIViewController(_ uiViewController: MapViewController, context: Context) {
markers.forEach { $0.map = uiViewController.map }
selectedMarker?.map = uiViewController.map
animateToSelectedMarker(viewController: uiViewController)
}
private func animateToSelectedMarker(viewController: MapViewController) {
guard let selectedMarker = selectedMarker else {
return
}
let map = viewController.map
if map.selectedMarker != selectedMarker {
map.selectedMarker = selectedMarker
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
map.animate(toZoom: kGMSMinZoomLevel)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
map.animate(with: GMSCameraUpdate.setTarget(selectedMarker.position))
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
map.animate(toZoom: 12)
})
}
}
}
}
}
animateToSelectedMarker(viewController)
işlevi, GMSMapView
'nin animate(with)
işlevini kullanarak bir dizi harita animasyonu gerçekleştirir.
ContentView
kullanıcısınınselectedMarker
kartınıMapViewControllerBridge
kullanıcısına aktarma
MapViewControllerBridge
yeni bağlamayı bildirdikten sonra ContentView
öğesini güncelleyerek MapViewControllerBridge
öğesinin oluşturulduğu selectedMarker
öğesini iletin.
ContentView
struct ContentView: View {
// ...
var body: some View {
// ...
GeometryReader { geometry in
ZStack(alignment: .top) {
// Map
MapViewControllerBridge(markers: $markers, selectedMarker: $selectedMarker)
// ...
}
}
}
}
Bu adımı tamamladığınızda listede yeni bir şehir seçildiğinde harita animasyonlu hale gelir.
Şehri vurgulamak için SwiftUI görünümünü canlandırma
SwiftUI, durum geçişleri için animasyonları gerçekleştirme işlemini ele alacağından görünümlere animasyon ekleme sürecini basitleştirir. Bunu göstermek için, harita animasyonu tamamlandıktan sonra görünümü seçilen şehre odaklayarak daha fazla animasyon ekleyeceksiniz. Bunu yapmak için aşağıdaki adımları uygulayın:
MapViewControllerBridge
hizmetineonAnimationEnded
kapanışı ekleme
SwiftUI animasyonu, daha önce eklediğiniz harita animasyonu dizisinden sonra gerçekleştirileceğinden onAnimationEnded
adlı yeni bir kapatma MapViewControllerBridge
içinde bildirin ve bu kapatmayı animateToSelectedMarker(viewController)
yöntemindeki son harita animasyonundan 0,5 saniye sonra çağırın.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
var onAnimationEnded: () -> ()
private func animateToSelectedMarker(viewController: MapViewController) {
guard let selectedMarker = selectedMarker else {
return
}
let map = viewController.map
if map.selectedMarker != selectedMarker {
map.selectedMarker = selectedMarker
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
map.animate(toZoom: kGMSMinZoomLevel)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
map.animate(with: GMSCameraUpdate.setTarget(selectedMarker.position))
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
map.animate(toZoom: 12)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: {
// Invoke onAnimationEnded() once the animation sequence completes
onAnimationEnded()
})
})
}
}
}
}
}
MapViewControllerBridge
içindeonAnimationEnded
uygulayın
onAnimationEnded
kapatmasını, MapViewControllerBridge
öğesinin ContentView
içinde örneklendirildiği yerde uygulayın. zoomInCenter
adlı yeni bir durum ekleyen ve clipShape
kullanarak görünümü değiştiren, ayrıca zoomInCenter
değerine bağlı olarak kırpılmış şeklin çapını değiştiren aşağıdaki kodu kopyalayıp yapıştırın.
ContentView
struct ContentView: View {
@State var zoomInCenter: Bool = false
// ...
var body: some View {
// ...
GeometryReader { geometry in
ZStack(alignment: .top) {
// Map
let diameter = zoomInCenter ? geometry.size.width : (geometry.size.height * 2)
MapViewControllerBridge(markers: $markers, selectedMarker: $selectedMarker, onAnimationEnded: {
self.zoomInCenter = true
})
.clipShape(
Circle()
.size(
width: diameter,
height: diameter
)
.offset(
CGPoint(
x: (geometry.size.width - diameter) / 2,
y: (geometry.size.height - diameter) / 2
)
)
)
.animation(.easeIn)
.background(Color(red: 254.0/255.0, green: 1, blue: 220.0/255.0))
}
}
}
}
- Animasyonları görmek için uygulamayı çalıştırın.
9. SwiftUI'a etkinlik gönderme
Bu adımda, GMSMapView
tarafından yayınlanan etkinlikleri dinleyecek ve bu etkinliği SwiftUI'ye göndereceksiniz. Özellikle, harita görünümüne bir temsilci atayacak ve kamera hareket etkinliklerini dinleyeceksiniz. Böylece, bir şehre odaklanıldığında ve harita kamerası bir hareketle hareket ettiğinde harita görünümünün odağı kaldırılacak ve haritanın daha fazlasını görebileceksiniz.
SwiftUI Koordinatörlerini Kullanma
GMSMapView
, kamera konumundaki değişiklikler veya bir işaretçiye dokunulması gibi etkinlikler yayınlar. Bu etkinlikleri dinleme mekanizması GMSMapViewDelegate protokolü aracılığıyla sağlanır. SwiftUI, özellikle UIKit görünüm denetleyicileri için temsilci olarak hareket etmek üzere kullanılan bir Koordinatör kavramını sunar. Bu nedenle, SwiftUI dünyasında bir Coordinator, GMSMapViewDelegate
protokolüne uygunluktan sorumlu olmalıdır. Bunun için aşağıdaki adımları uygulayın:
MapViewControllerBridge
içindeMapViewCoordinator
adlı bir Düzenleyici oluşturun.
MapViewControllerBridge
sınıfının içinde iç içe yerleştirilmiş bir sınıf oluşturun ve bu sınıfa MapViewCoordinator
adını verin. Bu sınıf, GMSMapViewDelegate
ile uyumlu olmalı ve MapViewControllerBridge
özelliğini bildirmelidir.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
// ...
final class MapViewCoordinator: NSObject, GMSMapViewDelegate {
var mapViewControllerBridge: MapViewControllerBridge
init(_ mapViewControllerBridge: MapViewControllerBridge) {
self.mapViewControllerBridge = mapViewControllerBridge
}
}
}
MapViewControllerBridge
içindemakeCoordinator()
uygulayın
Ardından, makeCoordinator()
yöntemini MapViewControllerBridge
içinde uygulayın ve önceki adımda oluşturduğunuz MapViewCoodinator
öğesinin bir örneğini döndürün.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
// ...
func makeCoordinator() -> MapViewCoordinator {
return MapViewCoordinator(self)
}
}
MapViewCoordinator
öğesini harita görünümünün temsilcisi olarak ayarlayın.
Özel koordinatör oluşturulduktan sonraki adım, koordinatörü görünüm denetleyicisinin harita görünümü için temsilci olarak ayarlamaktır. Bunu yapmak için makeUIViewController(context)
içinde görünüm denetleyicisi başlatmayı güncelleyin. Önceki adımda oluşturulan koordinatöre Context nesnesinden erişilebilir.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
// ...
func makeUIViewController(context: Context) -> MapViewController {
let uiViewController = MapViewController()
uiViewController.map.delegate = context.coordinator
return uiViewController
}
}
- Kamera hareket etkinliğinin yukarıya yayılması için
MapViewControllerBridge
öğesine kapatma ekleyin.
Amaç, görünümü kamera hareketleriyle güncellemek olduğundan MapViewControllerBridge
içinde mapViewWillMove
adlı bir boolean kabul eden yeni bir kapatma özelliği bildirin ve bu kapatmayı MapViewCoordinator
içindeki temsilci yönteminde mapView(_, willMove)
çağırın. SwiftUI görünümünün yalnızca hareketle ilgili kamera hareket etkinliklerine tepki verebilmesi için gesture
değerini kapatmaya iletin.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
var mapViewWillMove: (Bool) -> ()
//...
final class MapViewCoordinator: NSObject, GMSMapViewDelegate {
// ...
func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
self.mapViewControllerBridge.mapViewWillMove(gesture)
}
}
}
- ContentView'i,
mapWillMove
için bir değer iletilecek şekilde güncelleyin.
MapViewControllerBridge
tarihinde yeni bir kapanış ilan edildiğinden ContentView
parametresini, bu yeni kapanış için bir değer iletecek şekilde güncelleyin. Bu kapatma işleminde, taşıma etkinliği bir hareketle ilgiliyse Durum'u zoomInCenter
konumundan false
konumuna getirin. Bu işlem, harita bir hareketle taşındığında haritayı tekrar tam görünümde gösterir.
ContentView
struct ContentView: View {
@State var zoomInCenter: Bool = false
// ...
var body: some View {
// ...
GeometryReader { geometry in
ZStack(alignment: .top) {
// Map
let diameter = zoomInCenter ? geometry.size.width : (geometry.size.height * 2)
MapViewControllerBridge(markers: $markers, selectedMarker: $selectedMarker, onAnimationEnded: {
self.zoomInCenter = true
}, mapViewWillMove: { (isGesture) in
guard isGesture else { return }
self.zoomInCenter = false
})
// ...
}
}
}
}
- Yeni değişiklikleri görmek için uygulamayı çalıştırın.
10. Tebrikler
Bu aşamaya ulaştığınız için tebrik ederiz. Çok şey öğrendiniz. Umuyoruz ki öğrendikleriniz sayesinde artık iOS için Haritalar SDK'sını kullanarak kendi SwiftUI uygulamanızı oluşturabilirsiniz.
Öğrendikleriniz
- SwiftUI ile UIKit arasındaki farklar
- UIViewControllerRepresentable kullanarak SwiftUI ile UIKit arasında köprü kurma
- State ve Binding ile harita görünümünde değişiklik yapma
- Coordinator kullanarak harita görünümünden SwiftUI'a etkinlik gönderme
Sırada ne var?
- iOS için Haritalar SDK'sı
- iOS için Haritalar SDK'sının resmi dokümanları
- iOS için Yerler SDK'sı: Çevrenizdeki yerel işletmeleri ve ilgi çekici yerleri bulma
- maps-sdk-for-ios-samples
- GitHub'da, iOS için Haritalar SDK'sındaki tüm özellikleri gösteren örnek kod.
- SwiftUI: Apple'ın SwiftUI ile ilgili resmi belgeleri
- Aşağıdaki anketi yanıtlayarak en yararlı bulacağınız içerikleri oluşturmamıza yardımcı olun:
Başka hangi codelab'leri görmek istersiniz?
En çok ilgilendiğiniz codelab'i bulamıyor musunuz? Buradan yeni bir sorunla ilgili istekte bulunun.