2017-10-10 15 views
1

ユーザーがGoogleマップのマーカーをタップしたときに表示されるカスタムビューを作成しました。だから私のようにデリゲートメソッド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のfuctionは

@objc func buttonTapped(sender: UIButton) { 
     print("Yeah! Button is tapped!") 
    } 

として実装されているが、問題はそれが関数内で行っていないということです。私はthis tutorialをいれました答えに基づいて

UPDATE

ので、これは私が実装したものです:didTap

var tappedMarker = GMSMarker() 
var infoWindow = emergencyInfo(frame: CGRect(x: 0, y: 0, width: 200, height: 100)) 

その後:

まず、私はこれらの2つの変数を宣言しました私はこれをしました: func mapView(_mapView:GMSMapView、didTapマーカー:GMSMarker) - > Bool {

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方法を変更します。今、私は、コードを実行したときに、私はいくつかに基づいて#selector(buttonTapped)

fatal error: unexpectedly found nil while unwrapping an Optional value

を設定しています行にエラーが発生します

func mapView(_ mapView: GMSMapView, markerInfoWindow marker: GMSMarker) -> UIView? { 
     return UIView() 
} 

私がちょうど今"Title"与えたラベルinfoWindow.titleOfCenter.textを持っているので、私はこのエラーが左手側、すなわちinfoWindow.callNowButtonのために発生していることがわかりましたそれはクラッシュします同じエラーが表示されます。

答えて

0

だからこれは私が間違ってやっていたものです。私はUIViewクラスをxibファイルで初期化していませんでした。だから私は、コメントを追加しました:

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))を私が追加:func mapView(_ mapView: GMSMapView, didTap marker: GMSMarker) -> Bool {関数内

infoWindow = EmergencyViewController.instanceFromNib() 

を。

そして、グレンの答えはある程度は正しかった。

+0

Salam @ChaudhryTalha私のcustominfomarkerの中心点が間違った位置になりました。すなわち、マーカをタップすると、カスタムインフォーマラはマー​​カ上の中央に正しい位置を示さない。あなたはそれについてのアイデアがあれば分かち合ってください。 –

0

GMSMarkerはマップ上にイメージとして表示されるため、ボタンやその他のUI要素のコールバックを取得することはできません。

回避方法はdidTapWindowOfMarkerです。

this answerも参照してください。

+0

私は 'didTapWindowOfMarker'メソッドを追加しました。そして、ウィンドウ内の任意の場所をタップすると正しく機能します。しかし、そのためにボタンが1つだけあれば、2つのボタンがあり、どちらも実行する方法が異なります。 –

+0

申し訳ありませんが、私によると、タップの位置を取得していないので、それはできません。 –

+0

私の場合は、削除と編集の2つのアクションがありました。私がしたのは、私は編集ボタンだけを置いた後、ユーザーがタップすると、アクションシートで削除と編集を示しました。 –

2

ニヒルが正しいです。しかし、実際には少し努力と変更が必要なこのための甘い回避策があります。

我々はこの問題を回避するに進む前に、この答えhttps://stackoverflow.com/a/15281141/3231194読み:(私はすでにこれをやったし、それが動作します)この問題を回避するために次に

Possibly, as mentioned officially in documentation of Google Maps Android API, the below restriction regarding infowindows applies to Google Maps iOS SDK also :

Info window is not a live View, rather the view is rendered as an image onto the map. As a result, any listeners you set on the view are disregarded and you cannot distinguish between click events on various parts of the view. You are advised not to place interactive components — such as buttons, checkboxes, or text inputs — within your custom info window.

So basically clicking on any part of the infowindow will trigger only "didTapWindowOfMarker"

を、あなただけの簡単で、このチュートリアルhttp://kevinxh.github.io/swift/custom-and-interactive-googlemaps-ios-sdk-infowindow.htmlに従うことができます。

ボトムラインは、インフォウィドウをどのように地図に表示するかを変更する必要があります。カスタム情報ウィンドウをmarkerInfoWindowに戻す代わりに、UIView()に置き換えます。didTap markerでのカスタム情報ウィンドウの

次は、プレゼンテーション(または表示)を処理することですが、そこにあなたはまた、例えば、セレクタを設定し処理します:

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 
} 
+0

私の更新された質問がうまくいきますあなたの答えを実装し始めましたが、エラーがあります。 –

+0

質問をクリーンアップして、View Controllerのコード全体を追加することはできますか? :) そのほうがいい。 – Glenn

+0

私はこのクラスで多くのことをしているので、それはたくさんのコードになります。 'emergencyInfo'はUIViewクラスで、マーカーがタップされたときにスニペットとして表示している' .xib'を持っています。この '.xib'には2つのボタンがあります。エラーは 'UIView'がまだロードされていないか、それが何故nilを言っているのかと考えているからです。 –

関連する問題