How to define the order of overlapping MKAnnotationViews?

后端 未结 7 1424
谎友^
谎友^ 2020-11-30 06:29

I have several MKAnnotations (and their corresponding views) in my map, and it sometimes gets really crowded. Now, the annotations in my app come in two flavors: some are bo

7条回答
  •  感情败类
    2020-11-30 07:06

    Under iOS 11 the implementation of displayPriority broke all the solutions which use bringSubviewToFront or zPosition.

    If you override the annotation view's CALayer, you can wrestle control of zPosition back from the OS.

    class AnnotationView: MKAnnotationView {
    
        /// Override the layer factory for this class to return a custom CALayer class
        override class var layerClass: AnyClass {
            return ZPositionableLayer.self
        }
    
        /// convenience accessor for setting zPosition
        var stickyZPosition: CGFloat {
            get {
                return (self.layer as! ZPositionableLayer).stickyZPosition
            }
            set {
                (self.layer as! ZPositionableLayer).stickyZPosition = newValue
            }
        }
    
        /// force the pin to the front of the z-ordering in the map view
       func bringViewToFront() {
            superview?.bringSubviewToFront(toFront: self)
            stickyZPosition = CGFloat(1)
        }
    
        /// force the pin to the back of the z-ordering in the map view
       func setViewToDefaultZOrder() {
            stickyZPosition = CGFloat(0)
        }
    
    }
    
    /// iOS 11 automagically manages the CALayer zPosition, which breaks manual z-ordering.
    /// This subclass just throws away any values which the OS sets for zPosition, and provides
    /// a specialized accessor for setting the zPosition
    private class ZPositionableLayer: CALayer {
    
        /// no-op accessor for setting the zPosition
        override var zPosition: CGFloat {
            get {
                return super.zPosition
            }
            set {
                // do nothing
            }
        }
    
        /// specialized accessor for setting the zPosition
        var stickyZPosition: CGFloat {
            get {
                return super.zPosition
            }
            set {
                super.zPosition = newValue
            }
        }
    }
    

提交回复
热议问题