Swift MkMapViewで地図アプリ作成してみた（04）- トラッキングモードを切り替える（自作ボタン）

#記事一覧
[Swift MkMapViewで地図アプリ作成してみた（記事一覧）](https://qiita.com/rain_00_00_09/items/3151b3faf2303fe78312)

#ボタンに貼り付ける画像をAssets.xcassetsに取り込む

1. Image Setを追加する

    AppIcon下の白いスペースを右クリックして、New Image Setを押す。
    <img width="750" alt="ImageSet.png" src="https://qiita-image-store.s3.amazonaws.com/0/362635/9131311f-761e-6ced-6e08-3656a254bba2.png">

2. 追加したImage Setに画像を取り込む

    取り込みたい画像をドラックしてドロップする。
    <img width="750" alt="ImageSet2.png" src="https://qiita-image-store.s3.amazonaws.com/0/362635/5c09efdd-9f8c-f4a6-e547-a0040073ed59.png">

3. スクロールモード、ヘディングアップ、ノースアップ用のImage Setを追加する

    各Image Setを追加し、名前を変更する。
    <img width="750" alt="ImageSet3.png" src="https://qiita-image-store.s3.amazonaws.com/0/362635/4df4ad23-7091-8655-b24c-d14343e7e375.png">


#View Controllerにボタンを追加する

1. View Controllerにボタンを追加する

    「command + shift + l（エル）」でObjects Libraryを表示する。
    Buttonをstoryboard上のデバイスまでドラックしてドロップする。

    <img width="750" alt="button1.png" src="https://qiita-image-store.s3.amazonaws.com/0/362635/29ffbc04-fb18-c9fb-e6cf-6e291df6b091.png">

2. ボタンにノースアップの画像を設定する

    Imageのプルダウンで、Image Setが選択できるため、トラッキングモードの初期値であるノースアップ画像を設定する。
    <img width="750" alt="Button2.png" src="https://qiita-image-store.s3.amazonaws.com/0/362635/f96cfedf-cd91-12cc-4a85-2d2dba782724.png">

#追加したボタンのタッチダウンを検出する

1. タッチダウンした時にCallする関数を定義する

    ```swift:ViewController.swift：タッチダウンした時にCallする関数を定義する
    @IBAction func trackingBtnThouchDown(_ sender: AnyObject) {
        print("tracking Button Thouch Down!")
    }
    ```

2. タッチダウンした時にCallする関数を登録する

    Button Objectを右クリックし、Touch Downの右側の○をドラックして、View Controllerにドラックする。
    ドラックすると定義した関数が出力されるため選択する。
    <img width="750" alt="button3.png" src="https://qiita-image-store.s3.amazonaws.com/0/362635/532470c5-dc18-d793-a344-ca9fa8d580f6.png">

3. ▶︎を押してPCシミュレータでタッチダウンが検出されることを確認する

    タッチダウンすると(1.)で定義した関数がCallされる。
    <img width="750" alt="button4.png" src="https://qiita-image-store.s3.amazonaws.com/0/362635/51cc80d2-a8c2-0dbe-9ab7-339a28e3b439.png">

#タッチダウンされるとトラッキングモードを切り替える

1. タッチダウンでトラッキングモードを切り替える

    ノースアップ→ヘディングアップ→スクロールモード→ノースアップの順に切り替える。

    ```swift:ViewController.swift：タッチダウンでトラッキングモードを切り替える
@IBAction func trackingBtnThouchDown(_ sender: AnyObject) {
        switch mapView.userTrackingMode {
        case .follow:
            mapView.userTrackingMode = .followWithHeading
            break
        case .followWithHeading:
            mapView.userTrackingMode = .none
            break
        default:
            mapView.userTrackingMode = .follow
            break
        }
    }
    ```

2. 現在位置更新時に選択しているトラッキングモードに合わせて地図の中心位置を変更する

    [Swift MkMapViewで地図アプリ作成してみた（03）- 現在位置を地図の中心にする](https://qiita.com/rain_00_00_09/items/34b65640c7c839a379f4)で実装した処理を変更する。

    
    ```swift:ViewController.swift：変更前
    // CLLocationManagerのdelegate：現在位置取得
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations:[CLLocation]) {

    
        mapView.userTrackingMode = .follow
    
    ```
    
    変更前は現在位置が更新されると、無条件で地図の中心位置をノースアップで更新していた。

    ```swift:ViewController.swift：変更後
    // CLLocationManagerのdelegate：現在位置取得
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations:[CLLocation]) {

        switch mapView.userTrackingMode {
        case .followWithHeading:
            mapView.userTrackingMode = .followWithHeading
            break
        case .follow:
            mapView.userTrackingMode = .follow
            break
        default:
            break
        }
    
    ```
    
    変更後は、ヘディングアップであればヘディングアップ、ノースアップであればノースアップで更新する様に対応。
    ヘディングアップまたはノースアップ中に地図をスクロールすると、mapView.userTrackingModeは.noneに勝手に変更されるため、上記の実装でもスクロール中に現在位置に戻されることはない。

3. トラッキングモードに合わせてボタンの画像も切り替える

    storyboardのUIButtonとImage Setに登録した画像を紐付ける変数を定義する。

    ```swift:ViewController.swift：変更後
    class ViewController:   UIViewController,
                            CLLocationManagerDelegate,
                            UIGestureRecognizerDelegate {

        // storyboardのUIButtonを紐付ける変数
        @IBOutlet var trackingButton: UIButton!

        // Image Setに登録した画像を紐付ける変数
        let ImageHeadingUp :UIImage? = UIImage(named:"ImageHeadingUp")
        let ImageScrollMode :UIImage? = UIImage(named:"ImageScrollMode")
        let ImageNorthUp :UIImage? = UIImage(named:"ImageNorthUp")
    ```

    続いて、storyboardのUIButtonと変数を紐づける。
    trackingButtonを選択する。
    <img width="750" alt="button5.png" src="https://qiita-image-store.s3.amazonaws.com/0/362635/6b4c46e0-9ae8-a8c9-d587-383a990df677.png">

    最後に、(2.)で作成した関数にsetImage()でボタンの画像を変更する処理を追加する。

    ```swift:ViewController.swift：処理の追加後
    @IBAction func trackingBtnThouchDown(_ sender: AnyObject) {
        switch mapView.userTrackingMode {
        case .follow:
            mapView.userTrackingMode = .followWithHeading
            trackingButton.setImage(ImageHeadingUp, for: .normal)
            break
        case .followWithHeading:
            mapView.userTrackingMode = .none
            trackingButton.setImage(ImageScrollMode, for: .normal)
            break
        default:
            mapView.userTrackingMode = .follow
            trackingButton.setImage(ImageNorthUp, for: .normal)
            break
        }
    }
    ```

#記事一覧
[Swift MkMapViewで地図アプリ作成してみた（記事一覧）](https://qiita.com/rain_00_00_09/items/3151b3faf2303fe78312)