iOS地図(Map)アプリの作り方 長押しPin留め,OKボタン押しポップアップ

こんにちは。

最近運用していたWebアプリを閉鎖して、次に何作ろうか考え中のhardgumiです。
一個前に作成したのがWebアプリだったので、次はスマホアプリを開発しようと思い、今回はサンプルでiOS地図(Map)アプリを作りました。
自分への備忘録として、今後iOS地図アプリを作成される方の参考にsourceを共有します。

まずどんなアプリか記します。

地図スマホアプリ仕様

  • 自分の位置の地図を表示させる
  • 画面をロングタップするとピンを留めることができる
  • ピン留めした箇所は任意の画像(牛)で表示する
  • そのピンを押すと、タイトル[LongPressPin],サブタイトル[sub],右側にOKボタンを表示させる
  • OKボタンを押すと「OKボタン押下後 OKボタン押下後のポップアップ」と記載されたポップアップを表示させる

わかりやすく画像も載せときます。


開発環境

Swift 5.1
Xcode 11.1

Sponsored Link

実装 ViewController.swift

import UIKit
import MapKit
import CoreLocation

struct Annotation {
    let address: String
    let title: String?
    let subtitle: String?
}

class ViewController: UIViewController {
    
    @IBOutlet weak var mapView: MKMapView!
    var myLocationManager:CLLocationManager!
    
    //ロングタップしたときに立てるピンを定義
    var pinByLongPress:MKPointAnnotation!
    
    // ViewControllerのviewがロードされた後
    override func viewDidLoad() {
        super.viewDidLoad()
        configureSubviews()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    // 完全に遷移が行われ、スクリーン上に表示された時
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        startUpdatingLocation()
        
    }
    
    // 初期設定
    private func configureSubviews() {
        // CLLocationManagerのインスタンス生成
        myLocationManager = CLLocationManager()
        myLocationManager.delegate = self
        myLocationManager.desiredAccuracy = kCLLocationAccuracyBest
        myLocationManager.distanceFilter = 100
        myLocationManager.startUpdatingLocation()
        
        // MKMapViewのdelegate
        mapView.delegate = self
        mapView.mapType = .standard
        mapView.userTrackingMode = .follow
        
    }
    
    private func startUpdatingLocation() {
        switch CLLocationManager.authorizationStatus() {
        case .notDetermined:
            myLocationManager.requestWhenInUseAuthorization()
        default:
            break
        }
        myLocationManager.startUpdatingLocation()
    }

    //ロングタップを感知したときに呼び出されるメソッド
    @IBAction func longPressMap(_ sender: UILongPressGestureRecognizer) {
        
        if(sender.state != UIGestureRecognizer.State.began){
            return
        }
        
        //ロングタップから位置情報を取得
        let location:CGPoint = sender.location(in: mapView)
        
        //取得した位置情報をCLLocationCoordinate2D(座標)に変換
        let longPressedCoordinate:CLLocationCoordinate2D = mapView.convert(location, toCoordinateFrom: mapView)
        
        // インスタンス作成
        pinByLongPress = MKPointAnnotation()
        
        //ロングタップした位置の座標をピンに入力
        pinByLongPress.coordinate = longPressedCoordinate
        pinByLongPress.title = "LongPressPin"
        pinByLongPress.subtitle = "sub"
        //ピンを追加する(立てる)
        mapView.addAnnotation(pinByLongPress)
    }
}

// MARK: - MKMapViewDelegate
extension ViewController: MKMapViewDelegate {
    // アノテーションビューを返すメソッド
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {

        // 現在地表示かピンか区別
        if annotation is MKUserLocation {
            return nil
        }

        let pinView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: nil)

        pinView.glyphImage = UIImage(named:"pinImage")!

        // 吹き出しを表示可能にする
        pinView.canShowCallout = true

        let button = UIButton()
        button.frame = CGRect(x:0,y:0,width:40,height:40)
        button.setTitle("OK", for: .normal)
        button.setTitleColor(UIColor.white, for: .normal)
        button.backgroundColor = UIColor.green
        button.addTarget(self, action: #selector(sendLocation), for: .touchUpInside)

        // 右側にボタンを追加
        pinView.rightCalloutAccessoryView = button
        return pinView
    }

    // OKボタン押下時の処理
    @objc func sendLocation(){
        let alert = UIAlertController(title: "OKボタン押下後", message: "OKボタン押下後のポップアップ", preferredStyle: .alert)
        alert.addAction(UIAlertAction.init(title:"OK", style: .default, handler: { (_) in
            self.dismiss(animated: true, completion: nil)
        }))
        present(alert, animated: true, completion: nil)
    }
}


// MARK: - CLLocationManagerDelegate
extension ViewController: CLLocationManagerDelegate {
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        print("位置情報の取得に成功しました")
    }
    
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        let alert = UIAlertController(title: nil, message: "位置情報の取得に失敗しました", preferredStyle: .alert)
        alert.addAction(UIAlertAction.init(title: "OK", style: .default, handler: { (_) in
            self.dismiss(animated: true, completion: nil)
        }))
        present(alert, animated: true, completion: nil)
    }
}

以上です。
最後にSwiftでiOSアプリ開発した時に読んだ本だけ紹介しときます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です