delegates - 当用户在 SwiftUI 中触摸 GoogleMaps 的标记时如何更改 UI 状态?
问题描述
这个问题是关于 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()
}
}
这是谷歌地图的定义:
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
}
}
}
我希望有人可以帮助我,后来,这个问题对任何有同样需要的人都有用。
此致!
解决方案
一段时间后,我找到了解决它的方法。
关键字是“协调器”和“绑定”。
当然,我不确定这是正确的方法还是最好的方法,但至少它奏效了。
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
}
}
}
推荐阅读
- javascript - 使用 JavaScript 将存储为字符串的嵌套数组转换回嵌套数组
- kdb - KDB+/Q:如何理解语言参考中的定义?
- javascript - 如何使用js正则表达式匹配前面没有特殊单词的不确定数字
- vue.js - 路径更改时位置滚动没有改变 - vuejs
- c++ - 在 vs2019 中构建 ffmpeg 失败但不知道为什么
- java - 我是独立的 spark 集群,我们可以使用 map reduce compress 相关属性吗?如果使用这些属性真的有效吗?
- reactjs - 如何在多选材质 UI 中传递字符串值而不是传递事件?
- node.js - cloudinary 上传器未定义 node.js
- sql - postgres 从假期列表中获取下一个即时工作日期的存储过程
- python - 用while python插入逻辑