当用户点击谷歌地图上的标记时,我已经制作了自定义视图。所以我已将委托方法markerInfoWindow
写为:
func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
let infoWindow = Bundle.main.loadNibNamed("emergencyInfo", owner: self.view, options: nil)!.first! as! emergencyInfo
infoWindow.frame = CGRect(x: 0, y: 0, width: 200, height: 110)
infoWindow.titleOfCenter.text = marker.title
infoWindow.addressOfCenter.text = marker.snippet
infoWindow.callNowButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
return infoWindow
}
和buttonTapped
功能实现为
@objc func buttonTapped(sender: UIButton) {
print("Yeah! Button is tapped!")
}
但问题是它不会进入函数内部。
更新
根据答案,我开始关注this tutorial,所以这就是我实施的内容:
首先我宣布了这两个变量:
var tappedMarker = GMSMarker()
var infoWindow = emergencyInfo(frame: CGRect(x: 0, y: 0, width: 200, height: 100))
然后在didTap
我这样做了:
func mapView(_ mapView:GMSMapView,didTap marker:GMSMarker) - >布尔{
let location = CLLocationCoordinate2D(latitude: marker.position.latitude, longitude: marker.position.longitude)
tappedMarker = marker
infoWindow.removeFromSuperview()
infoWindow = emergencyInfo(frame: CGRect(x: 0, y: 0, width: 200, height: 100))
infoWindow.center = mapView.projection.point(for: location)
infoWindow.callNowButton.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside) //getting error on this line
self.view.addSubview(infoWindow)
return false
}
最后我将markerInfoWindow
方法更改为:
func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? {
return UIView()
}
现在当我运行代码时,我在设置#selector(buttonTapped)
致命错误:在解包可选值时意外发现nil
根据一些研究,我发现左侧出现了这个错误,即infoWindow.callNowButton
,因为我有一个标签infoWindow.titleOfCenter.text
,我刚刚给出了"Title"
那一刻,它崩溃了同样的错误。
答案 0 :(得分:3)
Nikhil是对的。然而,确实有一个很好的解决方法,需要一点努力和改变。
在我们继续解决之前,请先阅读此答案https://stackoverflow.com/a/15281141/3231194:
正如Google地图文档中正式提到的那样 Android API,以下关于infowindows的限制适用于 Google Maps iOS SDK也是:
信息窗口不是实时视图,而是视图呈现为 图像到地图上。因此,您在视图上设置的任何侦听器都是 被忽视,你无法区分各种点击事件 部分视图。建议您不要放置交互式组件 - 例如按钮,复选框或文本输入 - 在您的自定义中 信息窗口。
所以基本上点击infowindow的任何部分都只会触发 “didTapWindowOfMarker”
然后对于解决方法(我已经完成了这项工作),您可以按照本教程http://kevinxh.github.io/swift/custom-and-interactive-googlemaps-ios-sdk-infowindow.html进行操作,这很容易。
底线是:您需要更改向地图显示infoWindow的方式。您不会在markerInfoWindow
中返回自定义的infoWindow,而是将其替换为UIView()
。
接下来是处理didTap marker
中自定义infoWindow的演示(或显示),在那里您还将处理设置选择器,例如:
func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
guard let tappedJob = marker.userData as? Job else { return false }
self.mapView.selectedMarker = marker
jobInfoWindow?.buttons.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
jobInfoWindow?.job = tappedJob
jobInfoWindow?.center = mapView.projection.point(for: marker.position)
self.view.addSubview(jobInfoWindow!)
return false
}
答案 1 :(得分:1)
答案 2 :(得分:0)
所以这就是我做错了。我没有用xib文件初始化UIView类。所以我补充道:
class func instanceFromNib() -> emergencyInfo {
return UINib(nibName: "emergencyInfo", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! emergencyInfo
}
而不是infoWindow = emergencyInfo(frame: CGRect(x: 0, y: 0, width: 200, height: 100))
我添加了:
infoWindow = EmergencyViewController.instanceFromNib()
在func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {
函数内。
格伦的答案在某种程度上也是正确的。