【问题标题】:colored image for MKMarkerAnnotationView in MapKitMapKit 中 MKMarkerAnnotationView 的彩色图像
【发布时间】:2018-06-14 01:03:18
【问题描述】:

我正在为 iOS 构建一个应用程序,它允许用户基于位置存储图像。 现在我想在 iOS 中使用最新的AnnotationView (MKMarkerAnnotationView),因为它提供了自动集群。

我的问题是,如果未提供此类,则需要 glyphTintColor 将其设置为 UIColor().red。 iOS 正在使用这种颜色为整个图像着色。之后,图像只有这种颜色。 我尝试将glyphTintColor 设置为nil,但这会导致图像变红。我也尝试将其设置为UIColor(red:1.00, green:1.00, blue:1.00, alpha:0.0),但之后图像消失了,您只能看到标记本身。

我希望标记以原始颜色而不是单色显示图像。

谁能帮我解决这个问题?

这是我的完整代码:

func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
    if annotation is MKUserLocation {
        return nil
    }

    let identifier = "PinAnnotationIdentifier"

    var pinView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: identifier)

    pinView?.annotation = annotation
    pinView?.clusteringIdentifier = "clusterId"
    pinView?.rightCalloutAccessoryView = UIButton(type: .detailDisclosure)


    pinView?.canShowCallout = false
    pinView?.glyphImage = UIImage(named: "image")


    return pinView
}

【问题讨论】:

    标签: ios mapkit mkmapview mapkitannotation


    【解决方案1】:

    是的,你可以!你只需要稍微玩一下图层。 在创建新的 MKMarkerAnnotationView 时,创建 UIImageView 对象并在最后一层添加层(UIImageView)。

    override var annotation: MKAnnotation? {
        willSet {
    
            if let cluster = newValue as? MKClusterAnnotation {
                markerTintColor = UIColor(named: "Green")
                glyphText = "\(cluster.memberAnnotations.count)"
            }
    
            /* Check does received value is a MapMarkerAnnotation.swift object */
            guard let mapMarkerAnnotation = newValue as? MapMarkerAnnotation else { return }
    
            /* Assign properties */
            markerTintColor = Application.defaultColor
            displayPriority = .required
    
            /* Assign image */
            if let user = mapMarkerAnnotation.userInfo as? User {
                ImageManager.get(from: user.mainPhoto) { (image) in
    
                    let imageView = UIImageView(image: image)
                    imageView.frame = CGRect(x: 2, y: 2, width: 24, height: 24)
                    imageView.layer.cornerRadius = 24 / 2
                    imageView.clipsToBounds = true
                    self.layer.sublayers?[1].addSublayer(imageView.layer)
    
                    /* Assign current image but with clear color tint. */
                    self.glyphImage = image
                    self.glyphTintColor = .clear
                }
            }
        }
    }
    

    添加图像层后。在展开状态下添加图像层。

    func mapView(_ mapView: MKMapView, didSelect view: MKAnnotationView) {
    
        /* Check does annotation is an **MapMarker.swift** object. */
        if let mapMarkerAnnotationView = view as? MapMarkerAnnotationView {
            if let user = mapMarkerAnnotationView.userInfo as? User {
    
                /* Assign image */
                ImageManager.get(from: user.mainPhoto) { (image) in
    
                    let imageView = UIImageView(image: image)
                    imageView.frame = CGRect(x: 2, y: 2, width: 52, height: 52)
                    imageView.layer.cornerRadius = 52 / 2
                    imageView.clipsToBounds = true
    
                    /* Assign tag value */
                    imageView.layer.setValue(1, forKey: "tag")
    
                    /* check does image layer exist. */
                    if mapMarkerAnnotationView.layer.sublayers?[3].sublayers?.filter({($0.value(forKey: "tag") as? Int) == 1}).count == 0 {
                        mapMarkerAnnotationView.layer.sublayers?[3].addSublayer(imageView.layer)
                    }
                }
            }
        }
    

    祝你好运!

    【讨论】:

    • 由于某些原因,有时 sublayers 为 nil,因此无法分配图像。
    【解决方案2】:

    当你打电话时

    pinView?.glyphImage = UIImage(named: "image")
    

    pinView 来电

    glyphImage?.withRenderingMode(.alwaysTemplate)
    

    这可以轻松解决问题:只需覆盖withRenderingMode

    import UIKit
    
    class OriginalUIImage: UIImage {
    
        convenience init?(named name: String) {
            guard let image = UIImage(named: name),
                  nil != image.cgImage else {
                        return nil
            }
            self.init(cgImage: image.cgImage!)
        }
    
        override func withRenderingMode(_ renderingMode: UIImage.RenderingMode) -> UIImage {
            // both return statements work:
            return self
            // return super.withRenderingMode(.alwaysOriginal)
        }
    
    }
    

    现在你可以使用

    pinView?.glyphImage = OriginalUIImage(named: "image")
    

    【讨论】:

      【解决方案3】:

      很遗憾,无法以原始颜色而不是单色显示图像。

      glyphImage - MKMarkerAnnotationView | Apple Developer Documentation

      将字形图像创建为模板图像,以便可以将字形色调应用到它。

      字形也称为模板图像,是具有透明度、抗锯齿和无阴影的单色图像,它使用蒙版定义其形状。

      【讨论】:

      • 好的,非常感谢 :) 但是你认为通过扩展MKMarkerAnnotationView 并创建一个不设置单色的类可能吗? ;)
      • 好的,非常感谢 ;) 我想我会切换回在地图上显示图像的旧方式 ;)
      • 我想我为你找到了一个简单的答案
      猜你喜欢
      • 2022-08-22
      • 1970-01-01
      • 2022-10-15
      • 1970-01-01
      • 2019-06-26
      • 2017-11-10
      • 1970-01-01
      • 1970-01-01
      • 2015-07-09
      相关资源
      最近更新 更多