SwiftUI (iOS) ile iOS uygulamanıza harita ekleme

1. Başlamadan Önce

Bu codelab'de, iOS için Haritalar SDK'sını SwiftUI ile nasıl kullanacağınızı öğretiyoruz.

ekran görüntüsü-iphone-12-siyah@2x.png

Ön koşullar

  • Temel Swift bilgisi
  • SwiftUI hakkında temel bilgi

Yapacaklarınız

  • iOS için Haritalar SDK'sını etkinleştirerek SwiftUI kullanarak iOS uygulamasına Google Haritalar'ı ekleyin.
  • Haritaya işaretçiler ekleyin.
  • Bir SwiftUI görünümünden durumu GMSMapView nesnesine geçirin. Bunun tersi de geçerlidir.

Gerekenler

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 kurma

Henüz bir Google Cloud Platform hesabınız ve faturalandırmanın etkin olduğu bir projeniz yoksa faturalandırma hesabı ve proje oluşturmak için lütfen Google Haritalar Platformu'nu Kullanmaya Başlama kılavuzuna bakın.

  1. Cloud Console'da proje açılır menüsünü tıklayın ve bu codelab için kullanmak istediğiniz projeyi seçin.

  1. Google Cloud Marketplace'te bu codelab için gerekli olan Google Haritalar Platformu API'lerini ve SDK'larını etkinleştirin. Bunu yapmak için bu video veya bu dokümanlardaki adımları uygulayın.
  2. Cloud Console'un Kimlik Bilgileri sayfasında API anahtarı oluşturun. Bu video veya bu dokümanlardaki adımları uygulayabilirsiniz. Google Haritalar Platformu'na gönderilen tüm istekler bir API anahtarı gerektirir.

3. Başlangıç kodunu indir

En kısa sürede başlamanıza yardımcı olmak için aşağıda, bu codelab'i takip etmenize yardımcı olacak bazı başlangıç kodları verilmiştir. Çözüme geçebilirsiniz, ancak çözümü derlemek için tüm adımları izlemek isterseniz okumaya devam edin.

  1. git dosyasını yüklediyseniz depoyu klonlayın.
git clone https://github.com/googlecodelabs/maps-ios-swiftui.git

Alternatif olarak, kaynak kodu indirmek için aşağıdaki düğmeyi tıklayabilirsiniz.

  1. Kodu aldıktan sonra, cd terminalinde starter/GoogleMapsSwiftUI direktifine.
  2. iOS için Haritalar SDK'sını indirmek üzere carthage update --platform iOS uygulamasını çalıştırın
  3. 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ğlandı ve uygulandı:

  • AppDelegate - uygulamanın UIApplicationDelegate. iOS için Haritalar SDK'sı burada başlatılır.
  • City - bir şehri temsil eden yapı (şehirin bir koordinatını ve adını içerir).
  • MapViewController - Google Haritası (GMSMapView) içeren basit bir UIKit UIViewController
  • SceneDelegate - ContentView uygulaması için UIWindowSceneDelegate uygulaması.

Ayrıca, aşağıdaki sınıflar kısmi uygulamalara sahiptir ve bu Codelab'in sonuna kadar tamamlanacaktır:

  • ContentView - uygulamanızı içeren en üst düzey SwiftUI görünümü.
  • MapViewControllerBridge - bir UIKit görünümünü SwiftUI görünümüne bağlayan bir sınıf. Bu sınıf özellikle MapViewController adlı çocuğun SwiftUI'de erişilebilir olmasını sağlayacak sınıftır.

5. SwiftUI - UIKit Karşılaştırması

iOS 13'te, iOS uygulamaları geliştirmek için kullanıcı arayüzü yerine alternatif bir kullanıcı arayüzü çerçevesi olan SwiftUI kullanıma sunuldu. SwiftUI, bir öncekine ait UIKit'e kıyasla çok sayıda avantaj sunar. Birkaç örnek vermek gerekirse:

  • Durum değiştiğinde görünümler otomatik olarak güncellenir. Durum adlı nesneleri kullanırsanız, 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 geliştirme sürecini hızlandırır. Canlı önizlemeler, SwiftUI görünümünün önizlemesi Xcode'da görülebildiğinden, görsel değişiklikleri görmek için bir emülatöre kod oluşturma ve dağıtma gereksinimini en aza indirir.
  • Doğru bilginin kaynağı Swift. SwiftUI'deki tüm görüntülemeler Swift'te bildirildiği için artık arayüz oluşturucuyu kullanmanız gerekmez.
  • UIKit ile birlikte çalışır. UIKit ile birlikte çalışabilirlik özelliği, mevcut uygulamaların SwiftUI'yi mevcut görünümleriyle artımlı olarak kullanabilmesini sağlar. Ayrıca, iOS için Haritalar SDK'sı gibi SwiftUI'yi henüz desteklemeyen kitaplıklar da SwiftUI'de kullanılabilir.

Bazı dezavantajları da vardır:

  • SwiftUI yalnızca iOS 13 veya sonraki sürümlerde kullanılabilir.
  • Xcode önizlemelerinde görüntüleme hiyerarşisi incelenemez.

SwiftUI Durumu ve veri akışı

SwiftUI, bildirim temelli bir yaklaşım kullanarak kullanıcı arayüzü oluşturmanın yeni bir yolunu sunuyor. SwiftUI'ye, onun için tüm farklı durumlarda görünümünüzün nasıl görünmesini istediğinizi söylersiniz, gerisini sistem halleder. SwiftUI, bir etkinlik veya kullanıcı işlemi nedeniyle temel durum değiştiğinde görünümün güncellenmesini işler. Bu tasarım genellikle tek yönlü veri akışına yöneliktir. Bu tasarımın ayrıntıları bu codelab'in kapsamı dışında olsa da bu durumun Apple'ın Durum ve Veri Akışı dokümanlarında nasıl işlediğini okumanızı öneririz.

UIViewRepresentable veya UIViewControllerRepresentable kullanarak UIKit ve SwiftUI arasında köprü oluşturma

iOS için Haritalar SDK'sı UIKit üzerine kurulu olduğundan ve henüz SwiftUI uyumlu bir görünüm sağlamadığından SwiftUI'de SDK'nın UIViewRepresentable veya UIViewControllerRepresentable ile uyumlu olması gerekir. Bu protokoller, SwiftUI'nin sırasıyla UIKit tarafından oluşturulan UIView'leri ve UIViewController'ları içermesini sağlar. Her iki protokolü de SwiftUI görünümüne Google Haritası eklemek için kullanabilirsiniz. Ancak bir sonraki adımda, harita içeren bir UIViewController eklemek için UIViewControllerRepresentable işaretlemesine göz atacağız.

6. Harita ekle

Bu bölümde, Google Haritalar'ı SwiftUI görünümüne eklersiniz.

add-a-map-screen@2x.png

API anahtarınızı ekleme

Daha önce adımda oluşturduğunuz API anahtarının, hesabınızı uygulamada görüntülenecek haritayla ilişkilendirmek için 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. Şu anda SDK, "API_KEY" ön ekiyle "GMSServices.provideAPIKey()" ile başlatılmaktadır. Bu dizeyi API anahtarınızla değiştirin. Bu adımın tamamlanması, uygulama kullanıma sunulduğunda iOS için Haritalar SDK'sının başlatılmasını sağlar.

MapViewControllerBridge kullanarak Google Haritası ekleme

Artık API anahtarınız SDK'ya sağlandığına göre sonraki adım, haritayı uygulamada görüntülemektir.

Başlangıç kodunda sağlanan görüntüleme denetleyicisi (MapViewController), şu anda görünümünde GMSMapView. 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 bağlamanız gerekir. Bunu yapmak için:

  1. MapViewControllerBridge dosyasını Xcode'da açın.

Bu sınıf, SwiftUI görünümü olarak kullanılabilmesi için bir UIKit UIViewController öğesini sarmalamak üzere gereken protokol olan UIViewControllerRepresentable ile uyumludur. Diğer bir deyişle, bu protokole uymak bir UIKit görünümünü SwiftUI görünümüne bağlamanızı sağlar. Bu protokole uyulmak için iki yöntemin uygulanması gerekir:

  • makeUIViewController(context): Bu yöntem, SwiftUI tarafından çağrının temelini oluşturan UIViewController oluşturmak için kullanılır. Burada UIViewController öğesini örneklendirir ve ilk durumunu iletirsiniz.
  • updateUIViewController(_, context) - Bu yöntem, eyalet her değiştiğinde SwiftUI tarafından çağrılır. Burada, durum değişikliğine yanıt vermek için temelde UIViewController üzerinde herhangi bir değişiklik yapmanız gerekir.
  1. MapViewController oluşturun

makeUIViewController(context) işlevinin içinde yeni bir MapViewController oluşturun ve sonuç olarak bunu döndürün. Bunu yaptıktan sonra, MapViewControllerBridge cihazınız şu şekilde görünecektir:

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 artık MapViewController örneği oluşturduğuna göre sonraki adım, ContentView içinde bu yapıyı kullanarak bir harita görüntülemektir.

  1. ContentView dosyasını Xcode'da açın.

ContentView, SceneDelegate içinde örneklendi ve en üst düzey uygulama görünümünü içeriyor. Harita bu dosyanın içinden eklenir.

  1. body özelliğinde bir MapViewControllerBridge oluşturun.

Bu dosyanın body özelliğinde, sizin için zaten bir ZStack sağlanmış ve uygulanmış. ZStack şu anda daha sonraki bir adımda kullanacağınız, etkileşimli ve sürüklenebilir şehirlerin listesini içermektedir. Şimdilik, ZStack uygulamasının ilk alt görünümü olarak MapViewControllerBridge içinde uygulama oluşturun. Bunu yaptığınızda, ContentView içindeki body özelliğinin içeriği aşağıdaki gibi görünecektir:

İçerik Görüntüleme

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()
      } // ...
    }
  }
}
  1. Şimdi uygulamayı çalıştırın. Artık cihazınızın ekranında harita yükünü ve ekranın altına doğru sürüklenebilir şehir listesini görebilirsiniz.

7. Haritaya işaretçi ekleme

Önceki adımda, şehir listesini gösteren etkileşimli bir listenin yanına bir harita eklediniz. Bu bölümde, bu listedeki her şehir için işaretçiler ekleyeceksiniz.

Map-with-flags@2x.png

Eyalet olarak işaretçiler

ContentView şu anda cities statik mülkünde beyan edilen her şehri temsil eden GMSMarker listesinin markers adlı bir özelliğini bildirir. Bu özelliğin, SwiftUI tarafından yönetilmesi gerektiğini belirtmek için SwiftUI mülk sarmalayıcı Eyalet ile birlikte ek açıklamaya dikkat edin. Dolayısıyla, bu mülkte işaretçi ekleme veya kaldırma gibi bir değişiklik algılanırsa bu durumu kullanan görünümler güncellenir.

İçerik Görüntüleme

  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 öğesinin, şehir listesini CitiesList sınıfına aktararak oluşturmak için markers özelliğini kullandığını unutmayın.

Şehir Listesi

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)
      }
    }
  }
}

Bağlama Durumu aracılığıyla MapViewControllerBridge'e Eyalet Aktarma

markers mülkünden veri gösteren şehir listesine ek olarak, bu işaretçileri haritada görüntülemek için kullanılabilmesi için bu özelliği MapViewControllerBridge yapısına iletin. Bu izni vermek için:

  1. MapViewControllerBridge içinde @Binding ile ek açıklama eklenmiş yeni bir markers özelliği bildirin

MapViewControllerBridge

struct MapViewControllerBridge: : UIViewControllerRepresentable {
  @Binding var markers: [GMSMarker]
  // ...
}
  1. MapViewControllerBridge uygulamasında, markers özelliğinden yararlanmak için updateUIViewController(_, context) yöntemini güncelleyin

Önceki adımda belirtildiği gibi, her durum değişikliği için SwiftUI tarafından updateUIViewController(_, context) aranacak. Bu yöntemde haritayı güncellemek istediğimiz için işaretçileri markers dilinde görüntüleyin. Bunu yapmak için her bir işaretçinin map özelliğini güncellemeniz gerekir. Bu adımı tamamladıktan sonra MapViewControllerBridge cihazınız aşağıdaki gibi görünecektir:

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 }
  }
}
  1. ContentView mülkünden MapViewControllerBridge mülküne markers mülkü geçin

MapViewControllerBridge uygulamasına yeni bir mülk eklediğinizden, bu mülkün değerinin MapViewControllerBridge için başlatıcıda iletilmesi gerekir. Bu nedenle, uygulamayı oluşturmaya çalışırsanız uygulamanın derlenmeyeceğini unutmayın. Bu sorunu düzeltmek için ContentView öğesinin MapViewControllerBridge öğesinin oluşturulduğu yeri güncelleyin ve markers mülkünü şu şekilde iletin:

struct ContentView: View {
  // ...
  var body: some View {
    // ...
    GeometryReader { geometry in
      ZStack(alignment: .top) {
        // Map
        MapViewControllerBridge(markers: $markers)
        // ...
      }
    }
  }
}

$ ön ekinin, bağlı bir mülk beklediğinden markers öğesine MapViewControllerBridge iletmede kullanıldığına dikkat edin. $, Swift mülk sarmalayıcılarıyla kullanılmak üzere ayrılmış bir ön ektir. Bir Duruma uygulandığında Bağlama döndürür.

  1. Harita üzerinde görüntülenen işaretçileri görmek için uygulamayı çalıştırın.

8. Animasyonu seçili bir şehre animasyon olarak uygulama

Önceki adımda, Haritalar'a bir SwiftUI görünümünden diğerine geçerek işaretçiler eklediniz. Bu adımda, etkileşim sağlanan listede dokunulduktan sonra bir şehre/işaretçiye animasyon uygularsınız. Animasyonu gerçekleştirmek için, değişiklik gerçekleştiğinde haritanın kamera konumunu değiştirerek bir Durumda yapılan değişikliklere tepki verirsiniz. Harita kamerasının konsepti hakkında daha fazla bilgi edinmek için Kamera ve Görünüm başlıklı makaleye bakın.

animasyon-şehir@2x.png

Haritada seçili şehre animasyon ekleyin

Haritada seçilen bir şehre animasyon eklemek için:

  1. MapViewControllerBridge içinde yeni bir Bağlama tanımlayın

ContentView, sıfır olarak başlatılan ve listede bir şehir seçildiğinde güncellenen selectedMarker adlı bir Eyalet mülküne sahiptir. Bu işlem, ContentView içindeki CitiesList görünümü buttonAction tarafından gerçekleştirilir.

İçerik Görüntüleme

CitiesList(markers: $markers) { (marker) in
  guard self.selectedMarker != marker else { return }
  self.selectedMarker = marker
  // ...
}

Her selectedMarker değiştiğinde, MapViewControllerBridge bu durum değişikliğinin farkında olmalıdır. Böylece, harita seçilen işaretçiye animasyon ekleyebilir. Dolayısıyla, MapViewControllerBridge içinde GMSMarker türünde yeni bir Bağlama tanımlayın ve selectedMarker özelliğine bir ad verin.

MapViewControllerBridge

struct MapViewControllerBridge: UIViewControllerRepresentable {
  @Binding var selectedMarker: GMSMarker?
}
  1. selectedMarker her değiştiğinde haritayı canlandırmak için MapViewControllerBridge uygulamasını güncelleyin

Yeni bir Bağlama bildirildikten sonra, haritanın seçili işaretçiye animasyon eklemesi için MapViewControllerBridge's updateUIViewController_, context) işlevini güncellemeniz gerekir. Devam etmek için aşağıdaki kodu kopyalayın:

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's animate(with) işlevini kullanarak bir dizi harita animasyonu gerçekleştirir.

  1. MapViewControllerBridge adlı kişiye ContentView&#39s selectedMarker verin

MapViewControllerBridge için yeni Bağlama bildirildikten sonra devam edin ve MapViewControllerBridge öğesinin başlatıldığı selectedMarker bölgesinden geçmek için ContentView uygulamasını güncelleyin.

İçerik Görüntüleme

struct ContentView: View {
  // ...
  var body: some View {
    // ...
    GeometryReader { geometry in
      ZStack(alignment: .top) {
        // Map
        MapViewControllerBridge(markers: $markers, selectedMarker: $selectedMarker)
        // ...
      }
    }
  }
}

Bu adım tamamlandığında, listede yeni bir şehir seçildiğinde harita animasyonlu hale gelir.

Şehiri vurgulamak için SwiftUI görünümünü canlandırın

SwiftUI, Eyalet geçişleri için performansla ilgili animasyonları işleyeceğinden, animasyonların çok kolay görüntülenmesini sağlar. Bunu göstermek için, harita animasyonu tamamlandıktan sonra görünümü seçili şehre odaklayarak daha fazla animasyon ekleyeceksiniz. Bunun için aşağıdaki adımları uygulayın:

  1. MapViewControllerBridge için onAnimationEnded kapanışı ekleyin

SwiftUI animasyonu, daha önce eklediğiniz harita animasyonu dizisinden sonra gerçekleştirileceğinden, MapViewControllerBridge içinde onAnimationEnded adlı yeni bir kapatma bildirin ve animateToSelectedMarker(viewController) yöntemindeki son harita animasyonundan sonra 0,5 saniyelik bir gecikmeden sonra bu kapanışı ç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()
            })
          })
        }
      }
    }
  }
}
  1. MapViewControllerBridge içinde onAnimationEnded uygulayın

MapViewControllerBridge içinde ContentView başlatıldığı onAnimationEnded kapanışını uygulayın. Aşağıdaki kodu kopyalayıp zoomInCenter adlı yeni bir Durum ekleyin. Bu kod, clipShape kullanılarak görünümü değiştirir ve kırpılan şeklin çapını zoomInCenter değerine göre değiştirir.

İçerik Görüntüleme

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))
      }
    }
  }
}
  1. Animasyonları görmek için uygulamayı çalıştırın.

9. SwiftUI'ye etkinlik gönderme

Bu adımda, GMSMapView tarafından yayınlanan etkinlikleri dinler ve SwiftUI'ye gönderirsiniz. Özellikle, harita görünümüne bir yetki verir ve kamera hareket etkinliklerini dinlersiniz. Böylece bir şehir odaklanıldığında ve harita kamerası bir hareketten hareket ettiğinde, harita görünümünden daha fazlasını görebilmeniz için harita görünümü odaklanmaz.

SwiftUI Koordinatörlerini Kullanma

GMSMapView, kamera konumu değişiklikleri veya bir işaretçiye dokunulması gibi etkinlikler yayar. Bu etkinlikleri dinleme mekanizması, GMSMapViewAuth protokolünden geçer. SwiftUI, özellikle UIKit görünüm denetleyicileri için yetki verme amacıyla kullanılan Koordinatör kavramını tanıtmaktadır. Bu nedenle, SwiftUI dünyasında GMSMapViewDelegate protokolüne uymak bir Koordinatör tarafından yapılmalıdır. Bunun için aşağıdaki adımları uygulayın:

  1. MapViewControllerBridge içinde MapViewCoordinator adında bir Koordinatör oluşturun

MapViewControllerBridge sınıfının içinde iç içe yerleştirilmiş bir sınıf oluşturun ve bunu MapViewCoordinator olarak adlandırın. Bu sınıf, GMSMapViewDelegate ile uyumlu olmalı ve MapViewControllerBridge özelliğini mülk olarak tanımlamalıdır.

MapViewControllerBridge

struct MapViewControllerBridge: UIViewControllerRepresentable {
  // ...
  final class MapViewCoordinator: NSObject, GMSMapViewDelegate {
    var mapViewControllerBridge: MapViewControllerBridge

    init(_ mapViewControllerBridge: MapViewControllerBridge) {
      self.mapViewControllerBridge = mapViewControllerBridge
    }
  }
}
  1. MapViewControllerBridge içinde makeCoordinator() uygulayın

Ardından, makeCoordinator() içindeki MapViewControllerBridge yöntemini 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)
  }
}
  1. MapViewCoordinator öğesini harita görünümü için yetki verilen kullanıcı olarak ayarla

Özel koordinatör oluşturulduğunda, bir sonraki adım koordinatörü görüntüleme denetleyicisinin harita görünümü için yetki verilen kullanıcı olarak ayarlamaktır. Bunu yapmak için makeUIViewController(context) içerisindeki kumandayı ilk kullanıma hazırlama işlemini güncelleyin. Önceki adımda oluşturulan koordinatöre Bağlam nesnesinden erişilebilir.

MapViewControllerBridge

struct MapViewControllerBridge: UIViewControllerRepresentable {
  // ...
  func makeUIViewController(context: Context) -> MapViewController {
    let uiViewController = MapViewController()
    uiViewController.map.delegate = context.coordinator
    return uiViewController
  }
  1. Kameranın etkinliği taşıyabilmesi için MapViewControllerBridge konumuna bir kapanış ekleyin

Amaç, görünümü kamera hareketleriyle güncellemek olduğundan MapViewControllerBridge içindeki mapViewWillMove Boole'yı kabul eden yeni bir kapatma özelliği tanımlayın. Bu kapanışı, MapViewCoordinator içinde mapView(_, willMove) yetki verilmiş yönteminde çağırın. SwiftUI görünümünün yalnızca hareketle ilgili kamera taşıma etkinliklerine tepki verebilmesi için gesture değerini kapanışa geçirin.

MapViewControllerBridge

struct MapViewControllerBridge: UIViewControllerRepresentable {
  var mapViewWillMove: (Bool) -> ()
  //...

  final class MapViewCoordinator: NSObject, GMSMapViewDelegate {
    // ...
    func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
      self.mapViewControllerBridge.mapViewWillMove(gesture)
    }
  }
}
  1. mapWillMove için değer iletmek üzere ContentView'u güncelleyin

Yeni kapanışta MapViewControllerBridge tarihinde beyan edilen bu yeni kapanışa ilişkin değeri iletmek için ContentView değerini güncelleyin. Bu kapatmada, taşıma etkinliği bir hareketle ilgiliyse zoomInCenter durumunu false olarak değiştirin. Böylece, harita bir hareketle taşındığında harita etkili bir şekilde tam görünümde yeniden gösterilir.

İçerik Görüntüleme

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
        })
        // ...
      }
    }
  }
}
  1. Şimdi yeni değişiklikleri görmek için uygulamayı çalıştırın.

10. Tebrikler

Tebrikler! Birçok temel bilgi edindiniz. Umarız edindiğiniz dersler artık iOS için Haritalar SDK'sını kullanarak kendi SwiftUI uygulamanızı oluşturmanızı sağlar.

Öğrendikleriniz

Sonraki adım

  • iOS için Haritalar SDK'sı - iOS için Haritalar SDK'sı resmi dokümanları
  • iOS için Yerler SDK'sı - Çevrenizdeki yerel işletmeleri ve önemli yerleri bulun
  • maps-sdk-for-ios-samples - iOS için Haritalar SDK'sında bulunan tüm özellikleri gösteren GitHub'daki örnek kod.
  • SwiftUI - Apple’ın SwiftUI ile ilgili resmi dokümanları
  • Aşağıdaki soruyu cevaplayarak en çok yararlanacağınız içerikleri oluşturmamıza yardımcı olun:

Başka hangi codelab'leri görmek istersiniz?

Haritalarda veri görselleştirme Haritalarımın stilini özelleştirme hakkında daha fazla bilgi Haritalarda 3D etkileşimler için geliştirme

İstediğiniz codelab yukarıda listelenmiyor mu? Yeni bir sorun için istekte bulunun.