1. Sebelum Memulai
Codelab ini mengajarkan Anda cara menggunakan Maps SDK for iOS dengan SwiftUI.

Prasyarat
- Pengetahuan dasar Swift
- Pemahaman dasar tentang SwiftUI
Yang akan Anda lakukan
- Mengaktifkan dan menggunakan Maps SDK for iOS untuk menambahkan Google Maps ke aplikasi iOS menggunakan SwiftUI.
- Menambahkan penanda ke peta.
- Meneruskan status dari tampilan SwiftUI ke objek
GMSMapViewdan sebaliknya.
Yang akan Anda perlukan
- Xcode 11.0 atau versi yang lebih baru
- Akun Google dengan penagihan diaktifkan
- Maps SDK for iOS
- Carthage
2. Memulai persiapan
Untuk langkah pengaktifan berikut, aktifkan Maps SDK for iOS.
Menyiapkan Google Maps Platform
Jika Anda belum memiliki akun Google Cloud Platform dan project dengan penagihan diaktifkan, lihat panduan Memulai Google Maps Platform untuk membuat akun penagihan dan project.
- Di Cloud Console, klik menu drop-down project lalu pilih project yang ingin Anda gunakan untuk codelab ini.

- Aktifkan API dan SDK Google Maps Platform yang diperlukan untuk codelab ini di Google Cloud Marketplace. Untuk melakukannya, ikuti langkah-langkah dalam video ini atau dokumentasi ini.
- Buat kunci API di halaman Kredensial di Cloud Console. Anda dapat mengikuti langkah-langkah dalam video ini atau dokumentasi ini. Semua permintaan ke Google Maps Platform memerlukan kunci API.
3. Mendownload kode awal
Untuk membantu Anda memulai secepatnya, berikut beberapa kode awal untuk membantu Anda mengikuti codelab ini. Anda dapat langsung ke bagian solusi, namun jika Anda ingin mengikuti semua langkah untuk membuatnya sendiri, baca semuanya.
- Lakukan clone repositori jika sudah menginstal
git.
git clone https://github.com/googlecodelabs/maps-ios-swiftui.git
Atau, Anda dapat mengklik tombol berikut untuk mendownload kode sumber.
- Setelah mendapatkan kode, di terminal
cdpilih direktoristarter/GoogleMapsSwiftUI. - Jalankan
carthage update --platform iOSuntuk mendownload Maps SDK for iOS - Terakhir, buka file
GoogleMapsSwiftUI.xcodeprojdi Xcode
4. Ringkasan Kode
Dalam project permulaan yang Anda download, class berikut telah disediakan dan diterapkan untuk Anda:
AppDelegate-UIApplicationDelegateaplikasi. Di sini tempat Maps SDK for iOS akan diinisialisasi.City- struct yang mewakili kota (berisi nama dan koordinat kota).MapViewController-UIViewControllerUIKit sederhana yang berisi Google Maps (GMSMapView)SceneDelegate-UIWindowSceneDelegateaplikasi tempat instanceContentViewdibuat.
Selain itu, class berikut memiliki penerapan parsial dan akan Anda selesaikan pada akhir Codelab ini:
ContentView- tampilan SwiftUI tingkat teratas yang berisi aplikasi Anda.MapViewControllerBridge- class yang menjembatani tampilan UIKit ke tampilan SwiftUI. Secara khusus, ini adalah class yang akan membuatMapViewControllerdapat diakses di SwiftUI.
5. Menggunakan SwiftUI vs. UIKit
SwiftUI diperkenalkan di iOS 13 sebagai framework UI alternatif pengganti UIKit untuk mengembangkan aplikasi iOS. Dibandingkan dengan UIKit pendahulunya, SwiftUI menawarkan sejumlah keuntungan. Di antaranya:
- Tampilan diperbarui secara otomatis saat status berubah. Menggunakan objek yang disebut Status, setiap perubahan pada nilai dasar di dalamnya akan menyebabkan UI diperbarui secara otomatis.
- Pratinjau langsung memungkinkan pengembangan yang lebih cepat. Pratinjau langsung meminimalkan kebutuhan untuk mem-build dan men-deploy kode ke emulator untuk melihat perubahan visual karena pratinjau tampilan SwiftUI dapat langsung dilihat di Xcode.
- Sumber tepercaya ada di Swift. Semua tampilan di SwiftUI dideklarasikan di Swift, sehingga penggunaan Interface Builder tidak lagi diperlukan.
- Interoperabilitas dengan UIKit. Interoperabilitas dengan UIKit memastikan aplikasi yang ada dapat menggunakan SwiftUI secara bertahap bersama dengan tampilan yang ada. Selain itu, library yang belum mendukung SwiftUI, seperti Maps SDK for iOS, masih dapat digunakan di SwiftUI.
Tetapi ada juga beberapa kekurangan:
- SwiftUI hanya tersedia di iOS 13 atau versi yang lebih baru.
- Hierarki tampilan tidak dapat diperiksa dalam pratinjau Xcode.
Status dan aliran data SwiftUI
SwiftUI menawarkan cara baru untuk membuat UI menggunakan pendekatan deklaratif—Anda memberi tahu SwiftUI bagaimana Anda ingin tampilan diperlihatkan bersama dengan semua statusnya yang berbeda, dan sistem akan melakukan sisanya. SwiftUI menangani pembaruan tampilan setiap kali status yang mendasari berubah karena adanya peristiwa atau tindakan pengguna. Desain ini biasanya disebut aliran data searah. Meskipun spesifikasi desain ini berada di luar cakupan dalam codelab ini, sebaiknya Anda membaca cara kerjanya dalam dokumentasi Status dan Aliran Data Apple.
Menjembatani UIKit dan SwiftUI menggunakan UIViewRepresentable atau UIViewControllerRepresentable
Karena Maps SDK for iOS dibuat atas dasar UIKit dan belum menyediakan tampilan yang kompatibel dengan SwiftUI, penggunaannya di SwiftUI harus sesuai dengan UIViewRepresentable atau UIViewControllerRepresentable. Protokol ini memungkinkan SwiftUI menyertakan UIView dan UIViewController yang dibuat UIKit. Meskipun Anda dapat menggunakan salah satu protokol untuk menambahkan Google Maps ke tampilan SwiftUI, pada langkah berikutnya, kita akan melihat penggunaan UIViewControllerRepresentable untuk menyertakan UIViewController yang berisi peta.
6. Menambahkan peta
Di bagian ini, Anda akan menambahkan Google Maps ke tampilan SwiftUI.

Menambahkan kunci API
Kunci API yang Anda buat di langkah sebelumnya harus diberikan ke Maps SDK for iOS untuk mengaitkan akun Anda dengan peta yang akan ditampilkan di aplikasi.
Untuk memberikan kunci API Anda, buka file AppDelegate.swift lalu buka metode application(_, didFinishLaunchingWithOptions). Saat ini, SDK diinisialisasi melalui GMSServices.provideAPIKey() dengan string "YOUR_API_KEY". Ganti string tersebut dengan kunci API Anda. Dengan menyelesaikan langkah ini, Maps SDK for iOS akan diinisialisasi saat aplikasi diluncurkan.
Menambahkan Google Maps menggunakan MapViewControllerBridge
Setelah kunci API Anda diberikan ke SDK, langkah berikutnya adalah menampilkan peta di aplikasi.
Pengontrol tampilan yang disediakan dalam kode awal, MapViewController, saat ini berisi GMSMapView dalam tampilannya. Namun, karena pengontrol tampilan ini dibuat di UIKit, Anda harus menjembatani class ini ke SwiftUI sehingga dapat digunakan di dalam ContentView. Untuk melakukannya:
- Buka file
MapViewControllerBridgedi Xcode.
Class ini sesuai dengan UIViewControllerRepresentable yang merupakan protokol yang diperlukan untuk menggabungkan UIViewController UIKit, sehingga dapat digunakan sebagai tampilan SwiftUI. Dengan kata lain, mematuhi protokol ini memungkinkan Anda menjembatani tampilan UIKit ke tampilan SwiftUI. Untuk mematuhi protokol ini, diperlukan penerapan dua metode:
makeUIViewController(context)- metode ini dipanggil oleh SwiftUI untuk membuatUIViewControlleryang mendasari. Di sini Anda akan membuat instanceUIViewControllerdan meneruskan status awalnya.updateUIViewController(_, context)- metode ini dipanggil oleh SwiftUI setiap kali status berubah. Di sini Anda akan melakukan modifikasi padaUIViewControlleryang mendasari untuk bereaksi sebagai respons terhadap perubahan status.
- Buat
MapViewController
Di dalam fungsi makeUIViewController(context), buat instance MapViewController baru dan tampilkan sebagai hasilnya. Setelah melakukannya, MapViewControllerBridge Anda sekarang akan terlihat seperti ini:
MapViewControllerBridge
import GoogleMaps
import SwiftUI
struct MapViewControllerBridge: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> MapViewController {
return MapViewController()
}
func updateUIViewController(_ uiViewController: MapViewController, context: Context) {
}
}
Menggunakan MapViewControllerBridge di ContentView
Setelah MapViewControllerBridge membuat instance MapViewController, langkah berikutnya adalah menggunakan struct ini dalam ContentView untuk menampilkan peta.
- Buka file
ContentViewdi Xcode.
ContentView dibuat instance-nya di SceneDelegate dan berisi tampilan aplikasi tingkat atas. Peta akan ditambahkan dari dalam file ini.
- Buat
MapViewControllerBridgedalam propertibody.
Dalam properti body file ini, ZStack telah disediakan dan diterapkan untuk Anda. ZStack saat ini berisi daftar kota yang dapat berinteraksi dan dapat ditarik yang akan Anda gunakan di langkah berikutnya. Untuk saat ini, dalam ZStack, buat MapViewControllerBridge sebagai tampilan turunan pertama ZStack, sehingga peta akan ditampilkan di aplikasi di belakang tampilan daftar kota. Setelah melakukannya, konten properti body dalam ContentView akan terlihat seperti ini:
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()
} // ...
}
}
}
- Sekarang lanjutkan dan jalankan aplikasi. Anda akan melihat peta dimuat di layar perangkat beserta daftar kota yang dapat ditarik ke bagian bawah layar.
7. Menambahkan penanda ke peta
Pada langkah sebelumnya, Anda menambahkan peta bersama daftar yang dapat berinteraksi yang menampilkan daftar kota. Di bagian ini, Anda akan menambahkan penanda untuk setiap kota dalam daftar tersebut.

Penanda sebagai Status
ContentView saat ini mendeklarasikan properti bernama markers yang merupakan daftar GMSMarker. Kode ini mewakili setiap kota yang dideklarasikan di properti statis cities. Perhatikan bahwa properti ini dianotasi dengan Status wrapper properti SwiftUI untuk menunjukkan bahwa properti ini akan dikelola oleh SwiftUI. Jadi, jika ada perubahan yang terdeteksi dengan properti ini, seperti menambahkan atau menghapus penanda, tampilan yang menggunakan status ini akan diperbarui.
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
}
Perhatikan bahwa ContentView menggunakan properti markers untuk merender daftar kota dengan meneruskannya ke class CitiesList.
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)
}
}
}
}
Meneruskan Status ke MapViewControllerBridge melalui Binding
Selain daftar kota yang menampilkan data dari properti markers, teruskan properti ini ke struct MapViewControllerBridge agar dapat digunakan untuk menampilkan penanda tersebut pada peta. Untuk melakukannya:
- Deklarasikan properti
markersbaru dalamMapViewControllerBridgeyang dianotasi dengan@Binding
MapViewControllerBridge
struct MapViewControllerBridge: : UIViewControllerRepresentable {
@Binding var markers: [GMSMarker]
// ...
}
- Di
MapViewControllerBridge, perbarui metodeupdateUIViewController(_, context)untuk memanfaatkan propertimarkers
Seperti yang disebutkan di langkah sebelumnya, updateUIViewController(_, context) akan dipanggil oleh SwiftUI setiap kali status berubah. Dalam metode inilah kita ingin memperbarui peta sehingga menampilkan penanda di markers. Untuk melakukannya, Anda harus memperbarui properti map setiap penanda. Setelah menyelesaikan langkah ini, MapViewControllerBridge Anda akan terlihat seperti ini:
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 }
}
}
- Teruskan properti
markersdariContentViewkeMapViewControllerBridge
Karena Anda menambahkan properti baru di MapViewControllerBridge, maka nilai untuk properti ini harus diteruskan ke penginisialisasi untuk MapViewControllerBridge. Jadi, jika Anda mencoba mem-build aplikasi, Anda akan melihat bahwa aplikasi tidak akan dikompilasi. Untuk memperbaikinya, lakukan pembaruan pada ContentView tempat MapViewControllerBridge dibuat dan teruskan properti markers seperti berikut:
struct ContentView: View {
// ...
var body: some View {
// ...
GeometryReader { geometry in
ZStack(alignment: .top) {
// Map
MapViewControllerBridge(markers: $markers)
// ...
}
}
}
}
Perhatikan bahwa awalan $ digunakan untuk meneruskan markers ke MapViewControllerBridge karena mengharapkan properti terikat. $ adalah awalan yang dicadangkan untuk digunakan dengan wrapper properti Swift. Jika diterapkan ke Status, tindakan ini akan menampilkan Binding.
- Lanjutkan dan jalankan aplikasi untuk melihat penanda yang ditampilkan di peta.
8. Menganimasikan ke kota yang dipilih
Pada langkah sebelumnya, Anda menambahkan penanda ke peta dengan meneruskan Status dari satu tampilan SwiftUI ke tampilan lainnya. Pada langkah ini, Anda akan menganimasikan peta ke kota/penanda setelah diketuk di daftar yang dapat berinteraksi. Untuk menjalankan animasi, Anda akan bereaksi terhadap perubahan pada Status dengan memodifikasi posisi kamera peta saat perubahan tersebut terjadi. Untuk mempelajari lebih lanjut konsep kamera peta, lihat Kamera dan Tampilan.

Menganimasikan peta ke kota yang dipilih
Untuk menganimasikan peta ke kota yang dipilih:
- Tentukan Binding baru di
MapViewControllerBridge
ContentView memiliki properti Status yang disebut selectedMarker yang diinisialisasi ke nilai nol dan mendapatkan pembaruan setiap kali kota dipilih dalam daftar. Proses ini ditangani oleh tampilan CitiesList buttonAction dalam ContentView.
ContentView
CitiesList(markers: $markers) { (marker) in
guard self.selectedMarker != marker else { return }
self.selectedMarker = marker
// ...
}
Setiap kali selectedMarker berubah, MapViewControllerBridge harus mengetahui perubahan status ini agar dapat menganimasikan peta ke penanda yang dipilih. Jadi, tentukan Binding baru dalam MapViewControllerBridge dari jenis GMSMarker lalu beri nama properti selectedMarker.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
@Binding var selectedMarker: GMSMarker?
}
- Perbarui
MapViewControllerBridgeuntuk menganimasikan peta setiap kaliselectedMarkerberubah
Setelah Binding baru dideklarasikan, Anda perlu memperbarui fungsi updateUIViewController_, context) MapViewControllerBridge agar peta dianimasikan ke penanda yang dipilih. Lanjutkan dengan menyalin kode di bawah ini:
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)
})
}
}
}
}
}
Fungsi animateToSelectedMarker(viewController) akan menjalankan urutan animasi peta menggunakan fungsi animate(with) GMSMapView.
- Teruskan
selectedMarkerContentViewkeMapViewControllerBridge
Setelah Binding baru MapViewControllerBridge dideklarasikan, lanjutkan dan perbarui ContentView untuk diteruskan ke selectedMarker tempat MapViewControllerBridge dibuat instance-nya.
ContentView
struct ContentView: View {
// ...
var body: some View {
// ...
GeometryReader { geometry in
ZStack(alignment: .top) {
// Map
MapViewControllerBridge(markers: $markers, selectedMarker: $selectedMarker)
// ...
}
}
}
}
Menyelesaikan langkah ini sekarang akan menganimasikan peta setiap kali kota baru dipilih dalam daftar.
Menganimasikan tampilan SwiftUI untuk menekankan kota
SwiftUI membuat animasi tampilan menjadi sangat mudah karena SwiftUI akan menangani performa animasi untuk transisi Status. Untuk mendemonstrasikan ini, Anda akan menambahkan lebih banyak animasi dengan memfokuskan tampilan ke kota yang dipilih setelah animasi peta selesai. Untuk melakukannya, selesaikan langkah-langkah berikut:
- Tambahkan penutupan
onAnimationEndedkeMapViewControllerBridge
Karena animasi SwiftUI akan dijalankan setelah urutan animasi peta yang Anda tambahkan sebelumnya, deklarasikan penutupan baru bernama onAnimationEnded dalam MapViewControllerBridge, lalu panggil penutupan ini setelah penundaan 0,5 detik setelah animasi peta terakhir dalam metode animateToSelectedMarker(viewController).
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()
})
})
}
}
}
}
}
- Terapkan
onAnimationEndeddiMapViewControllerBridge
Terapkan penutupan onAnimationEnded tempat MapViewControllerBridge dibuat instance-nya dalam ContentView. Salin dan tempelkan kode berikut yang menambahkan Status baru bernama zoomInCenter sekaligus mengubah tampilan menggunakan clipShape dan memvariasikan diameter bentuk yang terpotong bergantung pada nilai zoomInCenter
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))
}
}
}
}
- Lanjutkan dan jalankan aplikasi untuk melihat animasi.
9. Mengirim peristiwa ke SwiftUI
Pada langkah ini, Anda akan memproses peristiwa yang dikeluarkan dari GMSMapView, dan mengirimkan peristiwa tersebut ke SwiftUI. Secara khusus, Anda akan menetapkan delegasi ke tampilan peta dan memproses peristiwa gerakan kamera, sehingga saat kota difokuskan dan kamera peta bergerak dari gestur, tampilan peta tidak akan fokus agar Anda bisa melihat semakin banyak peta.
Menggunakan Koordinator SwiftUI
GMSMapView memunculkan peristiwa seperti perubahan posisi kamera atau saat penanda diketuk. Mekanisme untuk memproses peristiwa ini adalah melalui protokol GMSMapViewDelegate. SwiftUI memperkenalkan konsep Koordinator yang digunakan secara khusus untuk bertindak sebagai delegasi untuk pengontrol tampilan UIKit. Jadi, dalam dunia SwiftUI, Koordinator harus bertanggung jawab untuk mematuhi protokol GMSMapViewDelegate. Untuk melakukannya, selesaikan langkah-langkah berikut:
- Buat Koordinator yang disebut
MapViewCoordinatordalamMapViewControllerBridge
Buat class bersarang di dalam class MapViewControllerBridge dan beri nama MapViewCoordinator. Class ini harus sesuai dengan GMSMapViewDelegate dan harus mendeklarasikan MapViewControllerBridge sebagai properti.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
// ...
final class MapViewCoordinator: NSObject, GMSMapViewDelegate {
var mapViewControllerBridge: MapViewControllerBridge
init(_ mapViewControllerBridge: MapViewControllerBridge) {
self.mapViewControllerBridge = mapViewControllerBridge
}
}
}
- Terapkan
makeCoordinator()diMapViewControllerBridge
Selanjutnya, terapkan metode makeCoordinator() dalam MapViewControllerBridge dan tampilkan instance MapViewCoodinator yang Anda buat di langkah sebelumnya.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
// ...
func makeCoordinator() -> MapViewCoordinator {
return MapViewCoordinator(self)
}
}
- Tetapkan
MapViewCoordinatorsebagai delegasi tampilan peta
Setelah koordinator kustom dibuat, langkah berikutnya adalah menetapkan koordinator sebagai delegasi untuk tampilan peta pengontrol tampilan. Untuk melakukannya, perbarui inisialisasi pengontrol tampilan di makeUIViewController(context). Koordinator yang dibuat dari langkah sebelumnya akan dapat diakses dari objek Context.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
// ...
func makeUIViewController(context: Context) -> MapViewController {
let uiViewController = MapViewController()
uiViewController.map.delegate = context.coordinator
return uiViewController
}
- Tambahkan penutupan ke
MapViewControllerBridgesehingga kamera yang akan memindahkan peristiwa dapat diterapkan
Karena tujuannya adalah memperbarui tampilan dengan gerakan kamera, deklarasikan properti penutupan baru yang menerima boolean dalam MapViewControllerBridge yang disebut mapViewWillMove, lalu panggil penutupan ini di metode delegasi mapView(_, willMove) dalam MapViewCoordinator. Teruskan nilai gesture ke penutupan, sehingga tampilan SwiftUI hanya dapat bereaksi terhadap peristiwa gerakan kamera terkait gestur.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
var mapViewWillMove: (Bool) -> ()
//...
final class MapViewCoordinator: NSObject, GMSMapViewDelegate {
// ...
func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
self.mapViewControllerBridge.mapViewWillMove(gesture)
}
}
}
- Perbarui ContentView agar meneruskan nilai untuk
mapWillMove
Dengan penutupan baru yang dideklarasikan di MapViewControllerBridge, perbarui ContentView agar dapat meneruskan nilai untuk penutupan baru ini. Dalam penutupan tersebut, alihkan Status zoomInCenter ke false jika peristiwa pergerakan terkait dengan gestur. Ini akan secara efektif menampilkan peta dalam tampilan lengkap lagi saat peta digerakkan oleh gestur.
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
})
// ...
}
}
}
}
- Lanjutkan dan jalankan aplikasi untuk melihat perubahan baru.
10. Selamat
Selamat karena telah membaca sampai sini. Anda telah mempelajari banyak hal, dan semoga pelajaran yang telah didapatkan tersebut membuat Anda kini bisa membuat sendiri aplikasi SwiftUI menggunakan Maps SDK for iOS.
Yang telah Anda pelajari
- Perbedaan antara SwiftUI dan UIKit
- Cara menjembatani SwiftUI dan UIKit menggunakan UIViewControllerRepresentable
- Cara membuat perubahan pada tampilan peta dengan Status dan Binding
- Cara mengirim peristiwa dari tampilan peta ke SwiftUI menggunakan Koordinator
Apa selanjutnya?
- Maps SDK for iOS - dokumentasi resmi untuk Maps SDK for iOS
- Places SDK for iOS - menemukan bisnis lokal dan lokasi menarik di sekitar Anda
- maps-sdk-for-ios-samples - kode contoh di GitHub yang menunjukkan semua fitur dalam Maps SDK for iOS.
- SwiftUI - Dokumentasi resmi Apple tentang SwiftUI
- Bantu kami membuat konten yang menurut Anda paling berguna dengan menjawab pertanyaan di bawah:
Apa saja codelab lain yang ingin Anda lihat?
Apakah codelab yang Anda inginkan tidak tercantum di atas? Ajukan permintaan bersama masalah baru di sini.