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

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

ただいまの
回答率

90.51%

  • Swift

    7272questions

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

  • iOS

    4008questions

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

  • iPhone

    979questions

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

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

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 232

clo.momo

score 14

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

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

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

markerView = MKMarkerAnnotationView()

//選択したアノテーションにボタンを追加する
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {  
       //アノテーションを緑にする   ここは機能する ⭕
            markerView.markerTintColor = .green
        }


    //吹き出しアクササリー押下時の呼び出しメソッド
    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
        if(control == view.leftCalloutAccessoryView) {
          //機能しない ❌
                markerView.markerTintColor = .blue
        } else {
       //右のボタンが押された場合はピンを消す。   機能する⭕
            mapView.removeAnnotation(view.annotation!)
        }
    }

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

      markerView = MKMarkerAnnotationView()

//選択したアノテーションにボタンを追加する
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        if annotation is MKUserLocation {
            return nil
        }

        //マーカーアノテーションにコールアウトを表示
        markerView.canShowCallout = true
        let pinID = "pin"
        var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: pinID) as? MKMarkerAnnotationView
        if annotationView == nil {
            annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: pinID)
            //マーカー設置の時アニメーションをつける
            markerView.animatesWhenAdded = true
            //マーカーを緑にする
            markerView.markerTintColor = .green//機能する⭕

            print("マーカーテストmarkerView:",markerView)//マーカーテストmarkerView: <MKMarkerAnnotationView: 0x7fb2ec016e00; frame = (121.802 248.686; 28 28); layer = <CALayer: 0x60000042ace0>>

            //左ボタンをアノテーションビューに追加する。
            let leftButton = UIButton()
            leftButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
            leftButton.setTitle("👍", for: UIControlState.normal)
            leftButton.setTitleColor(UIColor.black, for: UIControlState.normal)
            markerView.detailCalloutAccessoryView = leftButton

            //右ボタンをアノテーションビューに追加する。
            let rightButton = UIButton()
            rightButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
            rightButton.setTitle("❌", for: UIControlState.normal)
            rightButton.setTitleColor(UIColor.black, for: UIControlState.normal)
            markerView.rightCalloutAccessoryView = rightButton

        } else {
            annotationView!.annotation = annotation
        }

        return markerView
        }

    //吹き出しアクササリー押下時の呼び出しメソッド
    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
// 左ボタンが押された場合は青に変える
        if(control == view.leftCalloutAccessoryView) {
                markerView.markerTintColor = .blue//機能しない❌
            print("マーカーテスト2markerView:",markerView)//表示なし
        } else {
            //右のボタンが押された場合はピンを消す。
            mapView.removeAnnotation(view.annotation!)//機能する⭕
            print("マーカーテス3トmarkerView:",markerView)//マーカーテスト3markerView: <MKMarkerAnnotationView: 0x7fb2ec016e00; frame = (121.802 248.686; 28 28); layer = <CALayer: 0x60000042ace0>>
        }
    }
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • clo.momo

    2018/06/01 19:14

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

    キャンセル

  • tyobigorou

    2018/06/01 19:18

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

    キャンセル

  • clo.momo

    2018/06/01 19:29

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

    キャンセル

回答 2

check解決した方法

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 で赤に戻す
//選択したアノテーションにボタンを追加する
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        //ユーザーにアノテーションが適用されるのを防ぐ
        if annotation is MKUserLocation {
            return nil
        }

        let pinID = "pin"
        var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: pinID) as? MKMarkerAnnotationView
        if annotationView == nil {
            annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: pinID)
        } else {
            annotationView?.annotation = annotation
        }

        //マーカー設置の時アニメーションをつける
        annotationView?.animatesWhenAdded = true
        //マーカーアノテーションにコールアウトを表示
        annotationView?.canShowCallout = true
        //コールアウトを表示 ☆★☆★☆★これがないとタップしてもコールアウトが表示されない☆★☆★☆★
        let centerButton = UIButton()
        centerButton.frame = CGRect(x: 0, y: 0, width: 80, height: 40)
        centerButton.setTitle("バブル", for: UIControlState.normal)
        annotationView?.detailCalloutAccessoryView = centerButton

        //左ボタンをアノテーションビューに追加する。
        let leftButton = UIButton()
        leftButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
        leftButton.setTitle("左", for: UIControlState.normal)
        leftButton.setTitleColor(UIColor.black, for: UIControlState.normal)
        annotationView?.leftCalloutAccessoryView = leftButton


        //右ボタンをアノテーションビューに追加する。
        let rightButton = UIButton()
        rightButton.frame = CGRect(x: 0, y: 0, width: 40, height: 40)
        rightButton.setTitle("右", for: UIControlState.normal)
        rightButton.setTitleColor(UIColor.black, for: UIControlState.normal)
        annotationView?.rightCalloutAccessoryView = rightButton

        return annotationView
        }

    //吹き出しアクササリー押下時の呼び出しメソッド
    func mapView(_ mapView: MKMapView, annotationView view: MKAnnotationView, calloutAccessoryControlTapped control: UIControl) {
        // !!!!☆★☆★ 型キャストでmarkerTintColorを使えるようにする
        //if letの範囲をif~else~全体にすることでelseでもmarkerTintColorを使えるようにする
        if let annotationView = view as? MKMarkerAnnotationView {
            if(control == view.leftCalloutAccessoryView) {

                    annotationView.markerTintColor = .blue

            } else {
                mapView.removeAnnotation(view.annotation!)
                //マーカーを赤に戻さないと、青にして削除した後に追加したマーカーが青になる
                annotationView.markerTintColor = .red
            }
        }
    }

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/02 05:22

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

    キャンセル

  • 2018/06/02 12:02 編集

    //コールアウトを表示 ☆★☆★☆★これがないとタップしてもコールアウトが表示されない☆★☆★☆★
    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)

    を記入してないと、白文字なのか、
    「コールアウト」という文字は見えませんでした。

    キャンセル

  • 2018/06/02 12:09

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

    markerView.markerTintColor = .blue

    これを使いたいのですが、annotationViewはMKAnnotationViewなので使えません。
    使えるようにするにはどうすればいいのでしょうか?

    キャンセル

  • 2018/06/02 12:18

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

    キャンセル

  • 2018/06/02 13:13 編集

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

    キャンセル

  • 2018/06/02 13:59

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

    キャンセル

  • 2018/06/02 15:39 編集

    >> clo.momoさん

    調べてみると、detalCalloutAccessoryViewは
    subtitleに文字を表示しない代わりに違うUI パーツを表示したい時に
    使うものみたいですよ。
    下記をご参照ください

    https://dev.classmethod.jp/smartphone/ios-mapkit/

    なので、Callout自体はなくてもクリックで表示されるはずだと思います。

    キャンセル

-1

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/06/01 13:53 編集

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

    キャンセル

  • 2018/06/02 11:42

    解決方法を見つけたのですね。

    ググって、試行錯誤していましたが、
    解決コードを見いだすことができなかったです。

    載せていただた方法自分も試してみます。

    キャンセル

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

  • ただいまの回答率 90.51%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    swift Button タップ スワイプ

    現在、タップとスワイプの二つを一つのボタンで行おうとしています。 ボタンをタップしたらUIViewを出して ボタンをスワイプしたらそのボタンが指に沿って移動する・・・

  • 解決済

    swift スワイプ 座標判定 XY

    前提・実現したいこと 毎度毎度すみません・・・ 現在swiftで作っていて、場所Aにオブジェクトをスワイプし オブジェクトが場所Aに少しでも入っていたら、 オブジェクトを消

  • 解決済

    swift AppDeldateについて

    ボタンをクラス1で作り、タップ機能があり クラス2ではスワイプしたらの機能を作っていて スワイプし終わり、ある場所以外は元の位置に戻る・・・ と言うものを作っていて、クラ

  • 解決済

    addTargetのViewControllerに関するエラー

    Type "ViewController" has no member "num"というエラーが出ます。UIButtonをタップした時にUILabelに"0"を表示させたいのですが

  • 受付中

    classからUIButtonを作成したい

    viewcontrollerに複数のボタンを作成したいため、classを使って制御をしようと思いこのサイトを参考に作成しましたが、 self.view.addSubview(my

  • 解決済

    CollectionViewと連動してピン画像を変更させたい

    前提・実現したいこと タイトルの通りになります。 MapViewとCollectionViewが連動する形の画面を作りたいと思っています。 その際、ピンタップ時および、col

  • 解決済

    Swift UITextViewにて単語の上にルビを付ける方法

    趣味で小説サイトから小説をダウンロード、閲覧するアプリを作っています。 小説内で使われている単語などの上の行間に小さい文字でルビを付けたいと思っています。 iBook で購

  • 受付中

    カメラアクセスと写真のアップロードができない

    作ったアプリでカメラアクセスと写真のアップロードができません。 Xcodeから自分のiPhoneでエミュレータを起動したのですが Camera access ボタンとPhoto

同じタグがついた質問を見る

  • Swift

    7272questions

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

  • iOS

    4008questions

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

  • iPhone

    979questions

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

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