当用户在 SwiftUI 中触摸 GoogleMaps 的标记时如何更改 UI 状态?
Posted
技术标签:
【中文标题】当用户在 SwiftUI 中触摸 GoogleMaps 的标记时如何更改 UI 状态?【英文标题】:How to change UI state when user touch GoogleMaps' Marker in SwiftUI? 【发布时间】:2020-09-03 07:24:30 【问题描述】:这个问题是关于 SwiftUI 的。
我正在尝试显示地图并允许用户触摸任何可用的标记。发生这种情况时,我希望更改视图上的文本,以反映该用户的操作。
经过大量搜索,我认为解决方案可能接近 Observable 协议,但我就是想不出正确的方法。这是我的代码:
struct Home: View
// Here's the attribute I want to be changed when user touches the marker
var selectedMarker: GMSMarker?
var body: some View
VStack(spacing: 0)
// Condition to be applied when user touches the marker
if (selectedMarker == nil)
Text("No marker selected").padding()
else
Text("Now, there's a marker selected").padding()
GoogleMapsHome()
.navigationBarBackButtonHidden(true)
.navigationBarTitle(Text("Marker question"), displayMode: .inline)
struct Home_Previews: PreviewProvider
static var previews: some View
Home()
这是 GoogleMaps 的定义:
struct GoogleMapsHome: UIViewRepresentable
private let zoom: Float = 18
// Just for didactic purposes. Later, I'm going to use LocationManager
let lat: Double = -15.6692660716233
let lng: Double = -47.83980712156295
func makeUIView(context: Self.Context) -> GMSMapView
let camera = GMSCameraPosition.camera(
withLatitude: lat,
longitude: lng,
zoom: zoom)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
mapView.mapType = .hybrid
mapView.delegate = context.coordinator
return mapView
func updateUIView(_ mapView: GMSMapView, context: Context)
mapView.animate(toLocation: CLLocationCoordinate2D(latitude: lat, longitude: lng))
let position = CLLocationCoordinate2D(latitude: lat, longitude: lng)
let marker = GMSMarker(position: position)
marker.title = "You"
marker.map = mapView
func makeCoordinator() -> Coordinator
Coordinator(owner: self)
class Coordinator: NSObject, GMSMapViewDelegate, ObservableObject
let owner: GoogleMapsHome // access to owner view members,
init(owner: GoogleMapsHome)
self.owner = owner
@Published var selectedMarker: GMSMarker?
willSet objectWillChange.send()
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool
print("A marker has been touched by the user")
self.selectedMarker = marker
return true
我希望有人可以帮助我,以后,这个问题对任何有同样需要的人都有用。
最好的问候!
【问题讨论】:
【参考方案1】:过了一会儿,我找到了解决它的方法。
其中的关键字是“协调器”和“绑定”。
当然,我不确定这是正确的方法还是最好的方法,但至少它奏效了。
import Foundation
import SwiftUI
import GoogleMaps
struct Home: View
@State var selectedMarker: GMSMarker?
var body: some View
VStack(spacing: 0)
if (selectedMarker == nil)
Text("No marker selected").padding()
else
Text("There's a marker selected").padding()
GoogleMapsHome(selectedMarker: self.$selectedMarker)
.navigationBarBackButtonHidden(true)
.navigationBarTitle(Text("Map Test"), displayMode: .inline)
struct Home_Previews: PreviewProvider
static var previews: some View
Home()
struct GoogleMapsHome: UIViewRepresentable
private let zoom: Float = 18
let lat: Double = -15.6692660716233
let lng: Double = -47.83980712156295
@Binding var selectedMarker: GMSMarker?
func makeCoordinator() -> Coordinator
return Coordinator(
owner: self,
selectedMarker: $selectedMarker)
func makeUIView(context: Self.Context) -> GMSMapView
let camera = GMSCameraPosition.camera(
withLatitude: lat,
longitude: lng,
zoom: zoom)
let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
mapView.mapType = .hybrid
mapView.delegate = context.coordinator
return mapView
func updateUIView(_ mapView: GMSMapView, context: Context)
mapView.animate(toLocation: CLLocationCoordinate2D(latitude: lat, longitude: lng))
let position = CLLocationCoordinate2D(latitude: lat, longitude: lng)
let marker = GMSMarker(position: position)
marker.title = "You"
marker.map = mapView
class Coordinator: NSObject, GMSMapViewDelegate, ObservableObject
let owner: GoogleMapsHome // access to owner view members,
@Binding var selectedMarker: GMSMarker?
init(
owner: GoogleMapsHome,
selectedMarker: Binding<GMSMarker?>
)
self.owner = owner
_selectedMarker = selectedMarker
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool
print("A marker has been touched")
self.selectedMarker = marker
return true
【讨论】:
以上是关于当用户在 SwiftUI 中触摸 GoogleMaps 的标记时如何更改 UI 状态?的主要内容,如果未能解决你的问题,请参考以下文章
ios14 Xcode 12 - 触摸 SwiftUI 对象时精灵不显示,但触摸 SKScene 时工作