0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Swift MapKit】任意の画像でタイトル付きAnnotationを作る

Last updated at Posted at 2025-08-07

目標

MKMarkerAnnotationViewのようなテキスト付きのアノテーションを好きなSFSymbolsでつくる

Simulator Screenshot - iPhone 16 Pro Max - 2025-08-07 at 15.06.29.png

個人開発のアプリでお恥ずかしいが「城北町」のピンを作りたかった。「休憩」はデフォルトのMKMakerAnnotationView

方法

既存の部分の色を無理やり.clearにしてゴリ押した。
色が変わらなかったのでUIImageViewを一度経由して色を変えてレンダリングしたものを使う。

final class IconAnnotation: MKPointAnnotation {
    let icon: String
    
    init(title: String, icon: String) {
        self.icon = icon
        super.init()
        self.title = title
    }
}

final class IconAnnotationView: MKMarkerAnnotationView {
    static let identifier = "IconAnnotationView"
    override var annotation: MKAnnotation? {
        willSet {
            guard let iconAnnotation = newValue else { return }
            
            guard let baseImage = UIImage(systemName: iconAnnotation.icon) else { return }

            // サイズがそのままでは小さかったのでお好みで調整
            let scale: CGFloat = 1.5
            let newSize = CGSize(width: baseImage.size.width * scale,
                                 height: baseImage.size.height * scale)

            let imageView = UIImageView(image: baseImage)
            imageView.bounds = CGRect(origin: .zero, size: newSize)
            // 任意のカラー
            imageView.backgroundColor = .clear
            imageView.tintColor = .red

            // レンダリング
            let renderer = UIGraphicsImageRenderer(size: newSize)
            let renderedImage = renderer.image { _ in
                imageView.drawHierarchy(in: CGRect(origin: .zero, size: newSize), afterScreenUpdates: true)
            }

            image = renderedImage
            
            displayPriority = .required
            //既存のデザインを無効化
            markerTintColor = .clear
            glyphTintColor = .clear
            glyphImage = nil
        }
    }
}


extension IconAnnotationView {
    static func view(for mapView: MKMapView, annotation: FloatAnnotation) -> MKAnnotationView {
        var annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? FloatAnnotationView

        if annotationView == nil {
            annotationView = IconAnnotationView(annotation: annotation, reuseIdentifier: identifier)
        } else {
            annotationView?.annotation = annotation
        }

        return annotationView!
    }
}

//MKMapViewDelegate
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    if annotation is MKUserLocation {
        return nil
    }
    
    if let iconAnnotation = annotation as? IconAnnotation {
        return IconAnnotationView.view(for: mapView, annotation: iconAnnotation)
    }

    return nil
}
0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?