MKMapViewのMapへのタップ処理を禁止する

はじめに

UITableViewCellの中にMapを配置してマップをタップした時は親のViewにイベントを渡して処理を行い、MapViewの中のリンクボタンをタップした時の処理は現状のまま生かすような実装をする必要があり、いろいろ模索してみました。

解決策

MKMapViewのSubViewにはMKAttributionLabel_MKMapContentViewの2つのSubViewが存在します。
MKAttributionLabelは右下のリンクボタンで以下のようなURLに遷移します。_MKMapContentViewはMapに表示されるコンテンツを表示するViewです。

touches〜のメソッドをoverrideした場合touchesEndedが呼ばれずキャンセルしていないのにも関わらずtouchesCanceledが呼ばれてしまいます。

そこでpointメソッドでリンクボタン以外のイベントを伝播させないようにすることでMapViewが表示されている親にタップイベントを正常に渡すことができます。

final class TouchOnlyLinkMapView: MKMapView {
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        super.point(inside: point, with: event)

        let mKAttributionLabel = self.subviews.last!
        return mKAttributionLabel.layer.frame.contains(point)
    }
}

📝MapViewに乗っかるリンクの遷移先

https://gspe21-ssl.ls.apple.com/html/attribution-209.html

参考文献

[iOS] hitTest(:with:)を具体例で解説する