質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Q&A

解決済

2回答

807閲覧

コールアウトのボタンがタップされた時にアノテーションの色を変えるにはどうすればいいでしょうか?

clo.momo

総合スコア27

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

0グッド

0クリップ

投稿2018/06/01 01:18

編集2018/06/01 07:43

アノテーションのボタンをタップしたら色が変わるようにしたいのですが、よくわからないことになっています。

0. mapView:viewFor に markerView.markerTintColor = .green を記述して色が変わる
0. mapView:viewFor で色が変えられるのだから色を変えるコードは間違っていない
0. ところが、mapView:calloutAccessoryControlTapped で同じコードを使うと色が変わらない
0. control == view.leftCalloutAccessoryView が間違っている?
0. 念の為 markerView.markerTintColor = .blue をelse{}に入れてみたら色が変わらない
0. ということは、markerView.markerTintColor は mapView:calloutAccessoryControlTapped では使えない

では、markerView.markerTintColor を使わずにアノテーションの色を変えるにはどうすればいいのでしょうか?

Swift

1markerView = MKMarkerAnnotationView() 2 3//選択したアノテーションにボタンを追加する 4 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {   5       //アノテーションを緑にする   ここは機能する ⭕ 6 markerView.markerTintColor = .green 7 } 8 9 10 //吹き出しアクササリー押下時の呼び出しメソッド 11 func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { 12 if(control == view.leftCalloutAccessoryView) { 13          //機能しない ❌ 14 markerView.markerTintColor = .blue 15 } else { 16       //右のボタンが押された場合はピンを消す。   機能する⭕ 17 mapView.removeAnnotation(view.annotation!) 18 } 19 }

メソッドの全コードです。

Swift

1     markerView = MKMarkerAnnotationView() 2 3//選択したアノテーションにボタンを追加する 4 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 5 if annotation is MKUserLocation { 6 return nil 7 } 8 9 //マーカーアノテーションにコールアウトを表示 10 markerView.canShowCallout = true 11 let pinID = "pin" 12 var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: pinID) as? MKMarkerAnnotationView 13 if annotationView == nil { 14 annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: pinID) 15 //マーカー設置の時アニメーションをつける 16 markerView.animatesWhenAdded = true 17 //マーカーを緑にする 18 markerView.markerTintColor = .green//機能する⭕ 19 20 print("マーカーテストmarkerView:",markerView)//マーカーテストmarkerView: <MKMarkerAnnotationView: 0x7fb2ec016e00; frame = (121.802 248.686; 28 28); layer = <CALayer: 0x60000042ace0>> 21 22 //左ボタンをアノテーションビューに追加する。 23 let leftButton = UIButton() 24 leftButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40) 25 leftButton.setTitle("????", for: UIControlState.normal) 26 leftButton.setTitleColor(UIColor.black, for: UIControlState.normal) 27 markerView.detailCalloutAccessoryView = leftButton 28 29 //右ボタンをアノテーションビューに追加する。 30 let rightButton = UIButton() 31 rightButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40) 32 rightButton.setTitle("❌", for: UIControlState.normal) 33 rightButton.setTitleColor(UIColor.black, for: UIControlState.normal) 34 markerView.rightCalloutAccessoryView = rightButton 35 36 } else { 37 annotationView!.annotation = annotation 38 } 39 40 return markerView 41 } 42 43 //吹き出しアクササリー押下時の呼び出しメソッド 44 func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { 45// 左ボタンが押された場合は青に変える 46 if(control == view.leftCalloutAccessoryView) { 47 markerView.markerTintColor = .blue//機能しない❌ 48 print("マーカーテスト2markerView:",markerView)//表示なし 49 } else { 50 //右のボタンが押された場合はピンを消す。 51 mapView.removeAnnotation(view.annotation!)//機能する⭕ 52 print("マーカーテス3トmarkerView:",markerView)//マーカーテスト3markerView: <MKMarkerAnnotationView: 0x7fb2ec016e00; frame = (121.802 248.686; 28 28); layer = <CALayer: 0x60000042ace0>> 53 } 54 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/06/01 07:20 編集

markerView.markerTintColor = .greenとmarkerView.markerTintColor = .blueの下でprint("markerView:",markerView)してみたらどうなりますか? メソッドの記述が省略されていませんか?省略されているところも見たいのですが…。
退会済みユーザー

退会済みユーザー

2018/06/01 07:47 編集

表示なしだと通ってないみたいですね。mapView.removeAnnotation(view.annotation!)を markerView.markerTintColor = .blueに書き換えると色が変わりますか? 変わると思うので、「// 左ボタンが押された場合は青に変える」の下で print("control:",control)と記入してひだりボタンとやらを押してみてください
clo.momo

2018/06/01 07:45

ついでに、削除した後にも追加してみました。結果は青に変えるところだけ何も表示されませんでした。緑と削除の後に追加して表示された出力は質問の全コードに追加しました。
clo.momo

2018/06/01 07:49

removeを.blueに置き換えると青に変わりました!ということは、control == view.leftCalloutAccessoryViewが間違っているのではないでしょうか?
clo.momo

2018/06/01 08:05

記入すると確かに出力されました。ですが、青には変わりません。 control: <UIButton: 0x7ffb33cbc400; frame = (0 0; 40 40); opaque = NO; layer = <CALayer: 0x600001032100>>
退会済みユーザー

退会済みユーザー

2018/06/01 08:10

ああ、ごめんなさい、print("control:",control)とprint("view.leftCalloutAccessoryView:",view.leftCalloutAccessoryView)をしてください多分違う結果が出ると思うのですが。
clo.momo

2018/06/01 08:17

print("view.leftCalloutAccessoryView:",view.leftCalloutAccessoryView)はview.leftCalloutAccessoryView: nilでした。
退会済みユーザー

退会済みユーザー

2018/06/01 20:22 編集

ここから憶測なんですが、メソッドが違うのではと。コード全体に渡ってMKAnnotationのメソッドをつかっているようですが、操作している対象はMKMarkerAnnotationView()のように見えるので。private func mapView(_ mapView: MKMapView, annotationView view: MKMarkerAnnotationView, calloutAccessoryControlTapped control: UIControlをつかってみたらどうかと思うもですが? ボケててすいません、間違えました。controlに値が入ってきているようなので、メソッドはキチンと動いてますね。
退会済みユーザー

退会済みユーザー

2018/06/01 09:36 編集

markerView.detailCalloutAccessoryView = leftButtonのdetailと if(control == view.leftCalloutAccessoryView) のleftで表記が違うので、leftかdetailどちらかに統一するとうごくと思いますがどうですか?
clo.momo

2018/06/01 10:14

detailを指摘して頂いたおかげで謎が解けました!コールアウトはdetailがないと表示されないようです。本当に助かりました。ベストアンサーにさせて頂きたいのですが、このままじゃできないので、一度回答してもらえませんか?detailを指摘する回答をしてもらえればベストアンサーにさせていただきます。
退会済みユーザー

退会済みユーザー

2018/06/01 10:18

タイプミスなので、自己解決にしておいてください。
clo.momo

2018/06/01 10:29

タイプミスはタイプミスなのですが、そのおかげで解決しました。本当にありがとうございました。
guest

回答2

0

自己解決

  1. calloutはdetailCalloutAccessoryViewを設定
  2. .frame = CGRectで枠を作る
  3. setTitleなどで文字を入れるとコールアウトが表示される
  4. leftCalloutAccessoryViewとrightCalloutAccessoryViewでボタンを左と右に設置できる
  5. mapView:calloutAccessoryControlTappedでボタンが押された時のアクションを指定する

ボクが左ボタンを押してもうまく機能しなかった理由は、左ボタンにdetailを設定して、leftCalloutを設定していなかったから。

detailを設定しているからコールアウトが表示されるけど、leftを設定していないから左ボタンを押しても反応しない。

  1. mapView:calloutAccessoryControlTapped で annotationView に markerTintColor を使いたいので型キャスト?を使う。これで annotationView.markerTintColor = .blue と設定することができる
  2. このままだとマーカーを青にして削除した後にマーカーを追加すると青のマーカーを追加してしまうので、削除した後に annotationView.markerTintColor = .red で赤に戻す

Swift

1//選択したアノテーションにボタンを追加する 2 func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { 3 //ユーザーにアノテーションが適用されるのを防ぐ 4 if annotation is MKUserLocation { 5 return nil 6 } 7 8 let pinID = "pin" 9 var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: pinID) as? MKMarkerAnnotationView 10 if annotationView == nil { 11 annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: pinID) 12 } else { 13 annotationView?.annotation = annotation 14 } 15 16 //マーカー設置の時アニメーションをつける 17 annotationView?.animatesWhenAdded = true 18 //マーカーアノテーションにコールアウトを表示 19 annotationView?.canShowCallout = true 20 //コールアウトを表示 ☆★☆★☆★これがないとタップしてもコールアウトが表示されない☆★☆★☆★ 21 let centerButton = UIButton() 22 centerButton.frame = CGRect(x: 0, y: 0, width: 80, height: 40) 23 centerButton.setTitle("バブル", for: UIControlState.normal) 24 annotationView?.detailCalloutAccessoryView = centerButton 25 26 //左ボタンをアノテーションビューに追加する。 27 let leftButton = UIButton() 28 leftButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40) 29 leftButton.setTitle("左", for: UIControlState.normal) 30 leftButton.setTitleColor(UIColor.black, for: UIControlState.normal) 31 annotationView?.leftCalloutAccessoryView = leftButton 32 33 34 //右ボタンをアノテーションビューに追加する。 35 let rightButton = UIButton() 36 rightButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40) 37 rightButton.setTitle("右", for: UIControlState.normal) 38 rightButton.setTitleColor(UIColor.black, for: UIControlState.normal) 39 annotationView?.rightCalloutAccessoryView = rightButton 40 41 return annotationView 42 } 43 44 //吹き出しアクササリー押下時の呼び出しメソッド 45 func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) { 46 // !!!!☆★☆★ 型キャストでmarkerTintColorを使えるようにする 47 //if letの範囲をif~else~全体にすることでelseでもmarkerTintColorを使えるようにする 48 if let annotationView = view as? MKMarkerAnnotationView { 49 if(control == view.leftCalloutAccessoryView) { 50 51 annotationView.markerTintColor = .blue 52 53 } else { 54 mapView.removeAnnotation(view.annotation!) 55 //マーカーを赤に戻さないと、青にして削除した後に追加したマーカーが青になる 56 annotationView.markerTintColor = .red 57 } 58 } 59 }

投稿2018/06/01 10:39

編集2018/06/02 05:00
clo.momo

総合スコア27

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/06/01 20:22

回答する際にコードが省略されていたため、https://teratail.com/questions/128863 を参考にしていたのですが、解決済みだと思われますので、よろしければ、解決方法を記入してもらえませんか? MKMarkerAnnotationViewとMKPinAnnotationViewの違いに対する情報があまりないため、後の人がハマった際にこの質問の回答と合わせて大きな助けになると思います。
hameji

2018/06/02 03:03 編集

//コールアウトを表示 ☆★☆★☆★これがないとタップしてもコールアウトが表示されない☆★☆★☆★ let centerButton = UIButton() centerButton.frame = CGRect(x: 0, y: 0, width: 80, height: 40) centerButton.setTitle("コールアウト", for: UIControlState.normal) markerView.detailCalloutAccessoryView = centerButton とありますが、本当ですか? 自分の環境だと、これがなくても、 タップした際にcalloutが表示されましたよ? なしありを比較すると、calloutで表示されるViewの大きさが違いました。 当然真ん中にボタンがある分、大きいViewが表示されました。 また、centerButton.setTitleColor(UIColor.black, for: UIControlState.normal) を記入してないと、白文字なのか、 「コールアウト」という文字は見えませんでした。
clo.momo

2018/06/02 03:09

すみません。その前にバグが発生したので現在修正中です。 markerViewを使うとアノテーションが1つしか使えず他の不具合も起こるのでannotationViewに変更しました。最後の問題は左ボタンをタップしてマーカーの色を変えるところです。 markerView.markerTintColor = .blue これを使いたいのですが、annotationViewはMKAnnotationViewなので使えません。 使えるようにするにはどうすればいいのでしょうか?
clo.momo

2018/06/02 03:18

>>hamejiさん 再度detailCalloutAccessoryViewがなくても表示されるか試してみました。 結果はコールアウトは表示されませんでした。 こちらの環境では必要みたいです。 centerButtonは他のボタンを表示するために作っているので、私にとっては文字は見えなくても問題ありません。
退会済みユーザー

退会済みユーザー

2018/06/02 04:13 編集

なんだか、未解決になったようなので高評価取り消します。無責任に高評価押してごめんなさい。
clo.momo

2018/06/02 04:59

何度もすみません。今度こそ解決したはずです。
hameji

2018/06/02 06:39 編集

>> clo.momoさん 調べてみると、detalCalloutAccessoryViewは subtitleに文字を表示しない代わりに違うUI パーツを表示したい時に 使うものみたいですよ。 下記をご参照ください https://dev.classmethod.jp/smartphone/ios-mapkit/ なので、Callout自体はなくてもクリックで表示されるはずだと思います。
guest

0

すいません、よくわからなのですが、
上記のコードはそれぞれ、同じ色となってますが、

別々に(どちらかをコメントアウト)して、試してるんですよね?
それで、色がうまくいかないという事でいいんですか?

投稿2018/06/01 04:23

hameji

総合スコア1380

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

clo.momo

2018/06/01 04:54 編集

分かりにくくてすみません。そうです。別の色に変えようとしてもできません。 質問のコードを修正しました。
hameji

2018/06/02 02:42

解決方法を見つけたのですね。 ググって、試行錯誤していましたが、 解決コードを見いだすことができなかったです。 載せていただた方法自分も試してみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問