1. Прежде чем начать
В этой лабораторной работе вы узнаете, как использовать Maps SDK для iOS со SwiftUI.
Предпосылки
- Базовые знания Swift
- Базовое знакомство со SwiftUI
Что ты будешь делать
- Включите и используйте Maps SDK для iOS, чтобы добавить Карты Google в приложение iOS с помощью SwiftUI.
- Добавьте маркеры на карту.
- Передать состояние из представления SwiftUI в объект
GMSMapView
и наоборот.
Что вам понадобится
- Xcode 11.0 или новее
- Аккаунт Google с включенным платежным аккаунтом
- Карты SDK для iOS
- Карфаген
2. Настройте
Для следующего этапа активации включите Maps SDK для iOS .
Настройте платформу Google Карт
Если у вас еще нет учетной записи Google Cloud Platform и проекта с включенным выставлением счетов, ознакомьтесь с руководством по началу работы с платформой Google Maps , чтобы создать платежную учетную запись и проект.
- В Cloud Console щелкните раскрывающееся меню проекта и выберите проект, который вы хотите использовать для этой лаборатории кода.
- Включите API и SDK платформы Google Maps, необходимые для этой лаборатории кода, в Google Cloud Marketplace . Для этого выполните действия, описанные в этом видео или в этой документации .
- Создайте ключ API на странице учетных данных Cloud Console. Вы можете выполнить действия, описанные в этом видео или в этой документации . Для всех запросов к платформе Google Maps требуется ключ API.
3. Загрузите стартовый код
Чтобы вы начали как можно быстрее, вот некоторый начальный код, который поможет вам следовать этой кодовой лаборатории. Мы приветствуем вас, чтобы перейти к решению, но если вы хотите выполнить все шаги, чтобы создать его самостоятельно, продолжайте читать.
- Клонируйте репозиторий, если у вас установлен
git
.
git clone https://github.com/googlecodelabs/maps-ios-swiftui.git
Кроме того, вы можете нажать следующую кнопку, чтобы загрузить исходный код.
- Получив код, в терминале
cd
в каталогstarter/GoogleMapsSwiftUI
. - Запустите
carthage update --platform iOS
, чтобы загрузить Maps SDK для iOS. - Наконец, откройте файл
GoogleMapsSwiftUI.xcodeproj
в Xcode.
4. Обзор кода
В загруженном вами начальном проекте для вас были предоставлены и реализованы следующие классы:
-
AppDelegate
—UIApplicationDelegate
приложения. Здесь будет инициализирован Maps SDK для iOS. -
City
— структура, представляющая город (содержит название и координату города). -
MapViewController
— простой UIKitUIViewController
, содержащий карту Google ( GMSMapView ) -
SceneDelegate
—UIWindowSceneDelegate
приложения, из которого создается экземплярContentView
.
Кроме того, следующие классы имеют частичные реализации и будут завершены вами к концу этой лаборатории кода:
-
ContentView
— представление SwiftUI верхнего уровня, содержащее ваше приложение. -
MapViewControllerBridge
— класс, который соединяет представление UIKit с представлением SwiftUI. В частности, это класс, который сделаетMapViewController
доступным в SwiftUI.
5. Использование SwiftUI против UIKit
SwiftUI был представлен в iOS 13 как альтернативная платформа пользовательского интерфейса по сравнению с UIKit для разработки приложений iOS. По сравнению со своим предшественником UIKit, SwiftUI предлагает ряд преимуществ. Назвать несколько:
- Представления обновляются автоматически при изменении состояния. Используя объекты с именем State , любое изменение содержащегося в нем базового значения приведет к автоматическому обновлению пользовательского интерфейса.
- Предварительный просмотр в реальном времени ускоряет разработку. Предварительный просмотр в реальном времени сводит к минимуму необходимость создания и развертывания кода в эмуляторе, чтобы увидеть визуальные изменения, поскольку предварительный просмотр представления SwiftUI можно легко увидеть в Xcode.
- Источник истины находится в Swift. Все представления в SwiftUI объявлены в Swift, поэтому использование Interface Builder больше не требуется.
- Взаимодействует с UIKit. Взаимодействие с UIKit гарантирует, что существующие приложения могут постепенно использовать SwiftUI со своими существующими представлениями. Кроме того, библиотеки, которые еще не поддерживают SwiftUI, например Maps SDK для iOS, по-прежнему можно использовать в SwiftUI.
Есть и недостатки:
- SwiftUI доступен только на iOS 13 или выше.
- Иерархию представлений нельзя проверить в предварительных просмотрах Xcode.
Состояние SwiftUI и поток данных
SwiftUI предлагает новый способ создания пользовательского интерфейса с использованием декларативного подхода — вы указываете SwiftUI, как вы хотите, чтобы ваше представление выглядело вместе со всеми различными состояниями для него, а система сделает все остальное. SwiftUI обрабатывает обновление представления всякий раз, когда базовое состояние изменяется из-за события или действия пользователя. Этот дизайн обычно называют однонаправленным потоком данных . Хотя особенности этого дизайна выходят за рамки этой кодовой лаборатории, мы рекомендуем прочитать о том, как это работает, в документации Apple State and Data Flow .
Соединение UIKit и SwiftUI с помощью UIViewRepresentable или UIViewControllerRepresentable
Поскольку Maps SDK для iOS создан на основе UIKit и еще не предоставляет представление, совместимое со SwiftUI, для его использования в SwiftUI требуется соответствие либо UIViewRepresentable
, либо UIViewControllerRepresentable
. Эти протоколы позволяют SwiftUI включать встроенные в UIView
и UIViewController
соответственно. Хотя вы можете использовать любой протокол для добавления карты Google в представление SwiftUI, на следующем шаге мы рассмотрим использование UIViewControllerRepresentable
для включения UIViewController
, содержащего карту.
6. Добавьте карту
В этом разделе вы добавите Карты Google в представление SwiftUI.
Добавьте свой ключ API
Ключ API, который вы создали на предыдущем шаге, необходимо предоставить Maps SDK для iOS, чтобы связать вашу учетную запись с картой, которая будет отображаться в приложении.
Чтобы предоставить ключ API, откройте файл AppDelegate.swift
и перейдите к методу application(_, didFinishLaunchingWithOptions)
. В настоящее время SDK инициализируется с помощью GMSServices.provideAPIKey()
со строкой "YOUR_API_KEY". Замените эту строку своим ключом API. Выполнение этого шага приведет к инициализации Maps SDK для iOS при запуске приложения.
Добавьте карту Google с помощью MapViewControllerBridge
Теперь, когда ваш ключ API предоставлен SDK, следующим шагом будет отображение карты в приложении.
Контроллер представления, предоставленный в начальном коде, MapViewController
в настоящее время содержит GMSMapView
в своем представлении. Однако, поскольку этот контроллер представления был создан в UIKit, вам потребуется связать этот класс со SwiftUI, чтобы его можно было использовать внутри ContentView
. Для этого:
- Откройте файл
MapViewControllerBridge
в Xcode.
Этот класс соответствует протоколу UIViewControllerRepresentable , необходимому для создания оболочки UIKit UIViewController
чтобы его можно было использовать в качестве представления SwiftUI. Другими словами, соответствие этому протоколу позволяет вам соединить представление UIKit с представлением SwiftUI. Соответствие этому протоколу требует реализации двух методов:
-
makeUIViewController(context)
— этот метод вызывается SwiftUI для создания базовогоUIViewController
. Здесь вы должны создать экземпляр своегоUIViewController
и передать ему его начальное состояние. -
updateUIViewController(_, context)
— этот метод вызывается SwiftUI при каждом изменении состояния. Здесь вы можете вносить любые изменения в базовыйUIViewController
, чтобы реагировать на изменение состояния.
- Создайте
MapViewController
Внутри функции makeUIViewController(context)
экземпляр нового MapViewController
и верните его в качестве результата. После этого ваш MapViewControllerBridge
должен выглядеть так:
MapViewControllerBridge
import GoogleMaps
import SwiftUI
struct MapViewControllerBridge: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> MapViewController {
return MapViewController()
}
func updateUIViewController(_ uiViewController: MapViewController, context: Context) {
}
}
Используйте MapViewControllerBridge в ContentView
Теперь, когда MapViewControllerBridge
создает экземпляр MapViewController
, следующим шагом будет использование этой структуры в ContentView
для отображения карты.
- Откройте файл
ContentView
в Xcode.
ContentView
создается в SceneDelegate
и содержит представление приложения верхнего уровня. Карта будет добавлена из этого файла.
- Создайте
MapViewControllerBridge
в свойствеbody
.
В свойстве body
этого файла ZStack
уже предоставлен и реализован для вас. В настоящее время ZStack
содержит интерактивный и перетаскиваемый список городов, который вы будете использовать на следующем этапе. На данный момент в ZStack
создайте MapViewControllerBridge
в качестве первого дочернего представления ZStack
, чтобы карта отображалась в приложении за списком городов. После этого содержимое свойства body
в ContentView
должно выглядеть так:
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()
} // ...
}
}
}
- Теперь запустите приложение. Теперь вы должны увидеть загрузку карты на экране вашего устройства вместе с перетаскиваемым списком городов в нижней части экрана.
7. Добавьте маркеры на карту
На предыдущем шаге вы добавили карту вместе с интерактивным списком, отображающим список городов. В этом разделе вы добавите маркеры для каждого города в этом списке.
Маркеры как состояние
ContentView
в настоящее время объявляет свойство, называемое markers
, которое представляет собой список GMSMarker
представляющий каждый город, объявленный в статическом свойстве cities
. Обратите внимание, что это свойство снабжено аннотацией состояния оболочки свойства SwiftUI, чтобы указать, что оно должно управляться SwiftUI. Таким образом, если с этим свойством будут обнаружены какие-либо изменения, такие как добавление или удаление маркера, представления, использующие это состояние, будут обновлены.
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
использует свойство markers
для отображения списка городов, передавая его классу 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)
}
}
}
}
Передать состояние в MapViewControllerBridge через привязку
В дополнение к списку городов, отображающих данные из свойства markers
, передайте это свойство в структуру MapViewControllerBridge
, чтобы его можно было использовать для отображения этих маркеров на карте. Для этого:
- Объявите новое свойство
markers
вMapViewControllerBridge
, аннотированное с помощью@Binding
MapViewControllerBridge
struct MapViewControllerBridge: : UIViewControllerRepresentable {
@Binding var markers: [GMSMarker]
// ...
}
- В
MapViewControllerBridge
обновите методupdateUIViewController(_, context)
, чтобы использовать свойствоmarkers
.
Как упоминалось на предыдущем шаге, SwiftUI будет вызывать updateUIViewController(_, context)
при каждом изменении состояния. Именно в этом методе мы хотим обновить карту, чтобы отобразить маркеры в markers
. Для этого вам нужно будет обновить свойство map
каждого маркера. После выполнения этого шага ваш MapViewControllerBridge
должен выглядеть так:
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
изContentView
вMapViewControllerBridge
Поскольку вы добавили новое свойство в MapViewControllerBridge
, теперь требуется, чтобы значение этого свойства было передано в инициализатор для MapViewControllerBridge
. Итак, если вы попытаетесь собрать приложение, вы должны заметить, что оно не скомпилируется. Чтобы это исправить, обновите ContentView
, где MapViewControllerBridge
, и передайте свойство markers
следующим образом:
struct ContentView: View {
// ...
var body: some View {
// ...
GeometryReader { geometry in
ZStack(alignment: .top) {
// Map
MapViewControllerBridge(markers: $markers)
// ...
}
}
}
}
Обратите внимание, что префикс $
использовался для передачи markers
в MapViewControllerBridge
поскольку он ожидает связанное свойство. $
— это зарезервированный префикс для использования с обертками свойств Swift. При применении к состоянию возвращается Binding .
- Идите вперед и запустите приложение, чтобы увидеть маркеры, отображаемые на карте.
8. Анимация в выбранный город
На предыдущем шаге вы добавили маркеры на карту, передав состояние из одного представления SwiftUI в другое. На этом шаге вы перейдете к городу/маркеру после того, как вы коснетесь его в интерактивном списке. Чтобы выполнить анимацию, вы будете реагировать на изменения состояния, изменяя положение камеры на карте, когда происходит изменение. Чтобы узнать больше о концепции камеры карты, см. раздел Камера и вид .
Анимация карты для выбранного города
Чтобы анимировать карту для выбранного города:
- Определите новую привязку в
MapViewControllerBridge
ContentView
имеет свойство State, называемое selectedMarker
, которое инициализируется равным нулю и обновляется всякий раз, когда город выбирается в списке. Это обрабатывается CitiesList
представления buttonAction
в ContentView
.
ContentView
CitiesList(markers: $markers) { (marker) in
guard self.selectedMarker != marker else { return }
self.selectedMarker = marker
// ...
}
Всякий раз, когда selectedMarker
изменяется, MapViewControllerBridge
должен знать об этом изменении состояния, чтобы он мог анимировать карту для выбранного маркера. Итак, определите новую привязку внутри MapViewControllerBridge
типа GMSMarker
и назовите свойство selectedMarker
.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
@Binding var selectedMarker: GMSMarker?
}
- Обновите
MapViewControllerBridge
, чтобы анимировать карту при каждом измененииselectedMarker
.
После объявления новой привязки вам необходимо обновить MapViewControllerBridge
updateUIViewController_, context)
чтобы карта анимировалась до выбранного маркера. Идите вперед и сделайте это, скопировав код ниже:
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)
будет выполнять последовательность анимаций карты с использованием GMSMapView
animate(with)
.
- Передайте
selectedMarker
маркерContentView
вMapViewControllerBridge
Как только MapViewControllerBridge
новую привязку, обновите ContentView
, чтобы передать в selectedMarker
, где создается экземпляр MapViewControllerBridge
.
ContentView
struct ContentView: View {
// ...
var body: some View {
// ...
GeometryReader { geometry in
ZStack(alignment: .top) {
// Map
MapViewControllerBridge(markers: $markers, selectedMarker: $selectedMarker)
// ...
}
}
}
}
Выполнение этого шага теперь будет анимировать карту всякий раз, когда в списке будет выбран новый город.
Анимируйте представление SwiftUI, чтобы выделить город
SwiftUI делает анимацию представлений очень простой, поскольку он будет выполнять анимацию для переходов между состояниями. Чтобы продемонстрировать это, вы добавите больше анимаций, сфокусировав вид на выбранном городе после завершения анимации карты. Для этого выполните следующие шаги:
- Добавьте замыкание
onAnimationEnded
вMapViewControllerBridge
Поскольку анимация SwiftUI будет выполняться после последовательности анимации карты, которую вы добавили ранее, объявите новое замыкание с именем onAnimationEnded
в MapViewControllerBridge
и вызовите это замыкание после 0,5-секундной задержки после последней анимации карты в 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()
})
})
}
}
}
}
}
- Реализовать
onAnimationEnded
вMapViewControllerBridge
onAnimationEnded
замыкание onAnimationEnded, где MapViewControllerBridge
в ContentView
. Скопируйте и вставьте следующий код, который добавляет новое состояние с именем zoomInCenter
, а также изменяет представление с помощью clipShape
и изменяет диаметр обрезанной формы в зависимости от значения 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))
}
}
}
}
- Идите вперед и запустите приложение, чтобы увидеть анимацию!
9. Отправить событие в SwiftUI
На этом шаге вы будете прослушивать события, исходящие от GMSMapView
, и отправлять это событие в SwiftUI. В частности, вы настроите делегата на представление карты и будете прослушивать события перемещения камеры, чтобы, когда город сфокусировался и камера карты перемещалась из-за жеста, представление карты расфокусировалось, чтобы вы могли видеть больше карты.
Использование координаторов SwiftUI
GMSMapView
генерирует такие события, как изменение положения камеры или касание маркера. Механизм прослушивания этих событий осуществляется через протокол GMSMapViewDelegate . SwiftUI представляет концепцию координатора, который специально используется для работы в качестве делегата для контроллеров представления UIKit. Таким образом, в мире SwiftUI координатор должен отвечать за соответствие протоколу GMSMapViewDelegate
. Для этого выполните следующие шаги:
- Создайте координатора с именем
MapViewCoordinator
вMapViewControllerBridge
Создайте вложенный класс внутри класса MapViewControllerBridge
и назовите его MapViewCoordinator
. Этот класс должен соответствовать GMSMapViewDelegate
и должен объявлять MapViewControllerBridge
как свойство.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
// ...
final class MapViewCoordinator: NSObject, GMSMapViewDelegate {
var mapViewControllerBridge: MapViewControllerBridge
init(_ mapViewControllerBridge: MapViewControllerBridge) {
self.mapViewControllerBridge = mapViewControllerBridge
}
}
}
- Реализовать
makeCoordinator()
вMapViewControllerBridge
Затем реализуйте метод makeCoordinator()
в MapViewControllerBridge
и верните экземпляр MapViewCoodinator
, созданный на предыдущем шаге.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
// ...
func makeCoordinator() -> MapViewCoordinator {
return MapViewCoordinator(self)
}
}
- Установите
MapViewCoordinator
в качестве делегата представления карты
После создания пользовательского координатора следующим шагом будет установка координатора в качестве делегата для представления карты контроллера представления. Для этого обновите инициализацию контроллера представления в makeUIViewController(context)
. Созданный координатор из предыдущего шага будет доступен из объекта Context.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
// ...
func makeUIViewController(context: Context) -> MapViewController {
let uiViewController = MapViewController()
uiViewController.map.delegate = context.coordinator
return uiViewController
}
- Добавьте замыкание в
MapViewControllerBridge
, чтобы событие перемещения камеры могло распространяться вверх.
Поскольку цель состоит в том, чтобы обновить представление с помощью движений камеры, объявите новое свойство замыкания, которое принимает логическое значение в MapViewControllerBridge
, с именем mapViewWillMove
и вызовите это замыкание в методе делегата mapView(_, willMove)
в MapViewCoordinator
. Передайте значение gesture
замыканию, чтобы представление SwiftUI могло реагировать только на события перемещения камеры, связанные с жестами.
MapViewControllerBridge
struct MapViewControllerBridge: UIViewControllerRepresentable {
var mapViewWillMove: (Bool) -> ()
//...
final class MapViewCoordinator: NSObject, GMSMapViewDelegate {
// ...
func mapView(_ mapView: GMSMapView, willMove gesture: Bool) {
self.mapViewControllerBridge.mapViewWillMove(gesture)
}
}
}
- Обновите ContentView, чтобы передать значение для
mapWillMove
С новым замыканием, объявленным в MapViewControllerBridge
, обновите ContentView
, чтобы передать значение для этого нового замыкания. В этом замыкании переключите состояние zoomInCenter
на false
, если событие перемещения связано с жестом. Это эффективно снова покажет карту в полноэкранном режиме, когда карта перемещается с помощью жеста.
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
})
// ...
}
}
}
}
- Идите вперед и запустите приложение, чтобы увидеть новые изменения!
10. Поздравления
Поздравляем! Вы многое узнали, и, надеюсь, полученные уроки позволят вам создать собственное приложение SwiftUI с помощью Maps SDK для iOS.
Что вы узнали
- Различия между SwiftUI и UIKit
- Как соединить SwiftUI и UIKit с помощью UIViewControllerRepresentable
- Как внести изменения в представление карты с помощью состояния и привязки
- Как отправить событие из представления карты в SwiftUI с помощью координатора
Что дальше?
- Maps SDK для iOS – официальная документация по Maps SDK для iOS.
- Places SDK для iOS — находите местные предприятия и достопримечательности рядом с вами
- maps-sdk-for-ios-samples — пример кода на GitHub, демонстрирующий все функции Maps SDK для iOS.
- SwiftUI — официальная документация Apple по SwiftUI.
- Помогите нам создать наиболее полезный для вас контент, ответив на вопрос ниже:
Какие еще кодлабы вы хотели бы увидеть?
Нужная вам кодовая лаборатория не указана выше? Запросите его с новым выпуском здесь .