Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

[Swift Mapkit]独自のアノテーション設定・タップ領域拡大

解決したいこと・問題

iOSアプリの開発で、MapKitでカスタムアノテーションを設定した際に、アノテーションのタップ領域を拡大したいです。具体的には、タップ領域を画像のフレームサイズと同じにしたいのですが、タップ領域が拡大されず、正しく動作しません。

詳細

カスタム画像は、有楽町駅の座標にピンを指しています。
タップ領域がシビアなので、この黄色エリア(敢えて広げたものですがImageViewです)を触った時に作動するようにしたいのですが、拡大・縮小で座標がずれたりと上手くいきません。
IMG_0796.png

該当するソースコード

import UIKit
import MapKit
import CoreLocation

class CustomAnnotationView: MKAnnotationView {
    private let expandedTapArea: CGFloat = 20 // タップ領域の拡張量
    
    override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
        let targetArea = bounds.insetBy(dx: -expandedTapArea, dy: -expandedTapArea)
        if targetArea.contains(point) {
            return self
        }
        return nil
    }
    
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        let targetArea = bounds.insetBy(dx: -expandedTapArea, dy: -expandedTapArea)
        return targetArea.contains(point)
    }
}

class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {

    var mapView: MKMapView!
    var locationManager: CLLocationManager!

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 地図の設定
        mapView = MKMapView()
        mapView.frame = view.bounds
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        mapView.showsUserLocation = true
        view.addSubview(mapView)
        
        // 有楽町駅のピンを追加
        let yurakuchoLocation = CLLocationCoordinate2D(latitude: 35.675069, longitude: 139.763328)
        let yurakuchoPin = MKPointAnnotation()
        yurakuchoPin.coordinate = yurakuchoLocation
        yurakuchoPin.title = "有楽町駅"
        yurakuchoPin.subtitle = "ポテト"
        mapView.addAnnotation(yurakuchoPin)
        
        mapView.delegate = self
    }
    
    func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
        if let annotation = annotation as? MKPointAnnotation, annotation.title == "有楽町駅" {
            let identifier = "YurakuchoStation"
            var view: CustomAnnotationView
            
            if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? CustomAnnotationView {
                dequeuedView.annotation = annotation
                view = dequeuedView
            } else {
                view = CustomAnnotationView(annotation: annotation, reuseIdentifier: identifier)
                view.canShowCallout = true
                
                let imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 150, height: 150))
                imageView.contentMode = .scaleAspectFit
                imageView.center = view.center
                imageView.tag = 100
                imageView.image = UIImage(named: "TestImage")
                view.addSubview(imageView)
                
                let customButton = UIButton(type: .detailDisclosure)
                view.rightCalloutAccessoryView = customButton
            }
            
            return view
        }
        
        return nil
    }
}

自分で試したこと

expandedTapAreaの値を変更してみましたが、タップ領域が増えませんでした。
hitTest(_:with:)メソッドとpoint(inside:with:)メソッドが正しく実装されているか確認しましたが、特に問題はありませんでした。

わかる方ぜひアドバイス頂けますと幸いです。

0 likes

1Answer

MKAnnotationView自身のサイズが0×0となっているため、ほぼ画像の中央をタップしない限りヒットしませんね。
画像イメージをセットした時に、そのイメージのサイズをアノテーションのサイズに設定してあげればよいと思います。

    imageView.image = UIImage(named: "TestImage")
+   view.bounds.size = imageView.image!.size
    view.addSubview(imageView)
0Like

Your answer might help someone💌