GoogleMap の myLocation の現在位置が更新されたことを感知したい…。
だけど GMSMapViewDelegate にはそんなメソッドなさそうだなぁ…と思い どうしたものかとググっていました。
KVO (Key Value Observer ?) …? プロパティの値の変化を監視することができる…!
…KVOについて、いくつかの記事をググったのですが、一番自分にグッときたのがこちらでした。
KeyPath<T, Value> がどうしたらいいかわからず困っていたけど、このサイトの “\.プロパティ名” の記述を試したら、うまくいきました。 KeyPath についてちゃんと飲み込まないと気持ち悪いけど…とりあえず良しで ^^;
しかし…最後のクロージャーの部分が色々な記述ができるというのが…まだ慣れてない… ^^;
メソッドの引数なのに、()の中を飛び越えて?、()の後ろに { … } と記述できる発想がまだ出来ない… ^^;
そんな感じで、ググった記事を元に実装した内容は以下になります。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* KVO (Key Value Observer) | |
* | |
* GMSMapView (GoogleMap) の myLocation (CLLocation) の内容が変化したら...を取得 | |
*/ | |
import UIKit | |
import GoogleMaps | |
import CoreLocation | |
class MapViewController: UIViewController { | |
//GoogleMap | |
@IBOutlet weak var mapView: GMSMapView! | |
//KVO | |
private var keyValueObservations = [NSKeyValueObservation]() | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
// Do any additional setup after loading the view, typically from a nib. | |
// MapView 初期化 | |
self.initMapView(self.mapView) | |
//状態監視 | |
if (true) { | |
//NotificationCenterの例 | |
if (true) { | |
let center = NotificationCenter.default | |
//フォアグラウンドに復帰 | |
center.addObserver(self, | |
selector: #selector(MapViewController.viewWillEnterForeground(_:)), | |
name: NSNotification.Name.UIApplicationWillEnterForeground, | |
object: nil) | |
//バックグラウンドに退避 | |
center.addObserver(self, | |
selector: #selector(MapViewController.viewDidEnterBackground(_:)), | |
name: NSNotification.Name.UIApplicationDidEnterBackground, | |
object: nil) | |
} | |
//KVO (プロパティの変化を監視) | |
if (true) { | |
//GoogleMapの現在位置(myLocation)の更新を監視 | |
let keyValueObservation = self.mapView.observe(\.myLocation, options: [.new, .old], changeHandler: { (mapView, change) in | |
//change.old:変更前、 change.new: 変更後 | |
print(change) | |
}) | |
//こんな感じにクロージャーを()の中から追い出して記述することもできた (まだこの発想に慣れていない) | |
//let keyValueObservation = self.mapView.observe(\.myLocation, options: [.new, .old]) { (mapView, change) in /* ... */ } | |
//あとで破棄するので、作成した NSKeyValueObservation を保持しておく | |
self.keyValueObservations.append(keyValueObservation) | |
} | |
} | |
} | |
//破棄 | |
deinit { | |
//監視解除 | |
if (true) { | |
//NotificationCenter | |
if (true) { | |
let center = NotificationCenter.default | |
center.removeObserver(self, | |
name: NSNotification.Name.UIApplicationWillEnterForeground, | |
object: nil) | |
center.removeObserver(self, | |
name: NSNotification.Name.UIApplicationDidEnterBackground, | |
object: nil) | |
} | |
//KVO | |
if (true) { | |
for keyValueObservation in self.keyValueObservations { | |
keyValueObservation.invalidate() | |
} | |
self.keyValueObservations.removeAll() | |
} | |
} | |
} | |
} | |
// MARK: - NotificationCenter | |
extension MapViewController { | |
//フォアグラウンドに復帰したとき | |
@objc internal func viewWillEnterForeground(_ notification: Notification) { | |
} | |
//バックグラウンドに退避したとき | |
@objc internal func viewDidEnterBackground(_ notification: Notification) { | |
} | |
} |