地図アプリでマップの表示,スライダーの扱いについて学ぶ

##この記事でわかる主なこと
1.MapKitによる地図の表示
2.マップへのピン立て
3.UiSliderで値を制御する方法



##遭遇したエラー,解決できるかもしれないエラー
```swift

Could not cast value of type 'UISlider' (0x7fff897a56e8) to 'NSNumber'
```
```swift

Cannot convert value of type 'Float?' to expected argument type 'CLLocationDegrees' (aka 'Double')
```
```swift

Result of operator '==' is unused
```
```swift

Value of type '(UISlider) -> ()' has no member 'value'
```


###最終的にできるもの
<img width="200" alt="Simulator Screen Shot - iPhone SE (2nd generation) - 2020-04-23 at 09.02.15.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/4aeb0ab2-5080-5a6e-d8d9-60bb3cadfbfb.png">            <img width="200" alt="Simulator Screen Shot - iPhone SE (2nd generation) - 2020-04-23 at 09.01.59.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549093/4c21356f-ac2e-0d77-144b-5c7e831e96b1.png">


##1.MapKitによる地図の表示
地図を表示するためにMapKit,MKMapViewを用いた。

```swift

import MapKit
```
その後**viewDidLoad**の中で

```swift
let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(80.0,139.752)
        mapView.setCenter(location, animated: true)
```
のようにして最初に表示する場所を指定している。
**CLLocationCoordinate2D**と**CLLocationCoordinate2DMakeはそれぞれ
`WGS 84参照フレームを使用して指定された、場所に関連付けられた緯度と経度`
`緯度と経度の値を座標データ構造形式にフォーマットします`と説明されている。

##2.マップへのピン立て
住所から緯度経度を検索する、緯度軽度から住所を検索することができるCLGeocoderをインスタンス化し、
**.geocodeAddressString**　で住所から緯度経度を検索する。
クロージャー処理を行っているが、これはまた別の機会で記事を書く。

```swift
let pin = MKPointAnnotation()
                        pin.coordinate = targetCoordinate
                        pin.title = searchKey
                        self.mapView.addAnnotation(pin)
```
クロージャー処理の中にピンを立てる処理を施す。
##3.UISliderで値を制御する方法
アプリの中ではスライダーの動きに伴い地図を移動させている。(ほとんど海に移動してしまうが)
**sender.value**で値を取り出し、その値(latitudeValue)を**location:CLLocationCoordinate2D = CLLocationCoodinate2DMake**の中に緯度として入れ込んでいる。


```swift
@IBAction func latitudeSlider(_ sender: UISlider) {
        latitudeValue = Float(sender.value)
        latitudeLabel.text = "緯度は\(latitudeValue!)です"
        print(Double(latitudeValue!))
        let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(Double(latitudeValue!),Double(longitudeValue!))
        self.mapView.region = MKCoordinateRegion(center: location, latitudinalMeters: 500.0, longitudinalMeters: 500.0)
    }
```

##全体のソースコード

```swift
import UIKit
import MapKit
class ViewController: UIViewController, UITextFieldDelegate {
    var latitudeValue:Float?
    var longitudeValue:Float?
    @IBOutlet weak var mapView: MKMapView!
    @IBOutlet weak var textField: UITextField!
    @IBOutlet weak var latitudeSlider: UISlider!
    @IBOutlet weak var longitudeSlider: UISlider!
    @IBOutlet weak var latitudeLabel: UILabel!
    @IBOutlet weak var longitudeLabel: UILabel!
 
    override func viewDidLoad() {
        super.viewDidLoad()
        self.textField.delegate = self
        latitudeValue = 35.6815
        longitudeValue = 139.752
        let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(80.0,139.752)
        mapView.setCenter(location, animated: true)
        latitudeLabel.text = "緯度は\(80.0)です"
        longitudeLabel.text = "経度は\(139.752)です"
    }
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        let searchKey = textField.text!
        textField.resignFirstResponder()
        let geocoder = CLGeocoder()  //CLGeocoderのインスタンス化
        geocoder.geocodeAddressString(searchKey, completionHandler: {(placemarks, error) in
            
            if let unwrapPlacemarks = placemarks {//複数の位置情報が格納された配列unrapPlacemarks
                if let firstPlacemark = unwrapPlacemarks.first {//unrapPlacemarksの先頭の要素を抜き出す
                    if let location = firstPlacemark.location {//firstPlacemarksのうち緯度経度情報のみを抜き出す
                        let targetCoordinate = location.coordinate
                        let targetLatiude:Float = Float(targetCoordinate.latitude)
                        let targetLongitude:Float = Float(targetCoordinate.longitude)
                        print(targetCoordinate)
                        
                        //検索結果の位置にピンを置く
                        let pin = MKPointAnnotation()
                        pin.coordinate = targetCoordinate
                        pin.title = searchKey
                        self.mapView.addAnnotation(pin)
                        self.mapView.region = MKCoordinateRegion(center: targetCoordinate, latitudinalMeters: 500.0, longitudinalMeters: 500.0)
                        print("緯度は\(targetLatiude)")
                         //UISliderの移動とラベルの表示
                        
                        self.latitudeSlider.value = targetLatiude
                        self.longitudeSlider.value = targetLongitude
                        self.latitudeLabel.text = "緯度は\(targetLatiude)です"
                        self.longitudeLabel.text = "経度は\(targetLongitude)です"
                    }
                }
            }
            
        })
        return true   //geocoder.geocodeAddressString の戻り値
        
    }

    @IBAction func latitudeSlider(_ sender: UISlider) {
        latitudeValue = Float(sender.value)
        latitudeLabel.text = "緯度は\(latitudeValue!)です"
        print(Double(latitudeValue!))
        let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(Double(latitudeValue!),Double(longitudeValue!))
        self.mapView.region = MKCoordinateRegion(center: location, latitudinalMeters: 500.0, longitudinalMeters: 500.0)
    }
    
    @IBAction func longitudeSlider(_ sender: UISlider) {
        longitudeValue = Float(sender.value)
        longitudeLabel.text = "経度は\(longitudeValue!)です"
        print(Double(longitudeValue!))
        let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(Double(latitudeValue!),Double(longitudeValue!))
        self.mapView.region = MKCoordinateRegion(center: location, latitudinalMeters: 500.0, longitudinalMeters: 500.0)
    }
    @IBAction func decideButton(_ sender: Any) {
        let location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(Double(latitudeValue!), Double(longitudeValue!))
        mapView.region = MKCoordinateRegion(center: location, latitudinalMeters: 5000.0, longitudinalMeters: 5000.0)
    }
    @IBAction func changeMapStyleButton(_ sender: Any) {
        if mapView.mapType == .standard {
            mapView.mapType = .satellite
        } else if mapView.mapType == .satellite {
            mapView.mapType = .hybrid
        } else if mapView.mapType == .hybrid {
            mapView.mapType = .satelliteFlyover
        } else if mapView.mapType == .satelliteFlyover {
            mapView.mapType = .hybridFlyover
        } else if mapView.mapType == .hybridFlyover {
            mapView.mapType = .mutedStandard
        } else {
            mapView.mapType = .standard
        }
    }
}
```
##参考サイト
https://swift.tecc0.com/?p=694

##GitHub
https://github.com/Hyperbolic4183/Map-App