2016-09-24 115 views
0

我創建了一個顯示數字的自定義AnnotaionView。導致崩潰的MapKit自定義註釋視圖

導致最多問題的代碼似乎在佈局中。

class NumberAnnotationView: MKAnnotationView { 
    private var __number: Int 
    private var textLayer: CALayer! 
    private var shapeLayer: CAShapeLayer! 

    var number: Int { 
     get { 
      return __number 
     } 
     set { 
      __number = newValue 
      self.layer.setNeedsDisplay() 
     } 
    } 

    override init(annotation: MKAnnotation?, reuseIdentifier: String?) { 
     __number = 0 

     super.init(annotation: annotation, reuseIdentifier: reuseIdentifier) 

     self.frame = CGRect(x: 0, y: 0, width: 20, height: 20) 
     self.isOpaque = false 

     shapeLayer = CAShapeLayer() 
     shapeLayer.contentsScale = UIScreen.main.scale 
     shapeLayer.zPosition = 0 

     textLayer = CALayer() 
     textLayer.contentsScale = UIScreen.main.scale 
     textLayer.zPosition = 0 

     self.layer.addSublayer(shapeLayer) 
     self.layer.addSublayer(textLayer) 

     self.layer.contentsScale = UIScreen.main.scale 
     self.layer.delegate = self 
     self.layer.setNeedsDisplay() 
    } 
    required init?(coder aDecoder: NSCoder) { 
     fatalError("init(coder:) has not been implemented") 
    } 
    override func draw(_ layer: CALayer, in ctx: CGContext) { 
     if textLayer != nil && layer == textLayer { 
      UIGraphicsPushContext(ctx) 
      let textBounds = "\(number)".nsString.boundingRect(with: textLayer.frame.size, options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: [ 
       NSFontAttributeName: UIFont.systemFont(ofSize: 14) 
       ], context: nil) 

      textLayer.frame = CGRect(x: (layer.frame.size.width - textBounds.width)/2, y: (layer.frame.size.height - textBounds.height)/2, width: textBounds.width, height: textBounds.height) 

      "\(number)".nsString.draw(in: textLayer.frame, withAttributes: [ 
       NSFontAttributeName: UIFont.systemFont(ofSize: 14) 
       ]) 

      UIGraphicsPopContext() 
     } else if shapeLayer != nil && layer == shapeLayer { 
      UIGraphicsPushContext(ctx) 
      let path = UIBezierPath(roundedRect: layer.frame, cornerRadius: 5.0) 
      shapeLayer.path = path.cgPath 
      shapeLayer.fillColor = UIColor.white.cgColor 
      shapeLayer.strokeColor = UIColor.blue.cgColor 
      shapeLayer.lineWidth = 2.0 
      UIGraphicsPopContext() 
     } else if layer == self.layer { 
      shapeLayer.setNeedsDisplay() 
      textLayer.setNeedsDisplay() 
     } 
    } 
    override func layoutSublayers(of layer: CALayer) { 
     if (layer == self.layer) { 
      shapeLayer.frame = layer.bounds 
      textLayer.frame = layer.bounds 
      shapeLayer.delegate = self 
      textLayer.delegate = self 
     } 
    } 
} 

它不斷崩潰,並給了我一個令人費解的堆棧...

#0 0x000000010d3b294e in -[UIGestureEnvironment _queueGestureRecognizersForResetIfFinished:]() 
#1 0x000000010d3b28ed in -[UIGestureEnvironment _cancelGestureRecognizers:]() 
#2 0x000000010ce93803 in -[UIApplication _cancelGestureRecognizersForView:]() 
#3 0x000000010cf2e832 in -[UIView(Hierarchy) _willMoveToWindow:]() 
#4 0x000000010cf2f3d5 in __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke() 
#5 0x000000010cf2f2fe in -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]() 
.......... 
#40240 0x000000010cf2f3f3 in __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke() 
#40241 0x000000010cf2f2fe in -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]() 
#40242 0x000000010cf2f3f3 in __85-[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]_block_invoke() 
#40243 0x000000010cf2f2fe in -[UIView(Hierarchy) _makeSubtreePerformSelector:withObject:withObject:copySublayers:]() 
#40244 0x000000010cf2d31f in __UIViewWillBeRemovedFromSuperview() 
#40245 0x000000010cf2cf32 in -[UIView(Hierarchy) removeFromSuperview]() 
#40246 0x000000010c9e21e0 in -[MKAnnotationContainerView removeAnnotationView:]() 
#40247 0x000000010c872391 in -[MKMapView removeAnnotationRepresentation:]() 
#40248 0x000000010c930438 in -[MKAnnotationManager _removeRepresentationForAnnotation:fromCull:]() 
#40249 0x000000010c92f519 in -[MKAnnotationManager updateVisibleAnnotations]() 
#40250 0x000000010c862fe5 in -[MKMapView _didChangeRegionMidstream:]() 
#40251 0x000000010c867e24 in -[MKMapView mapLayer:didChangeRegionAnimated:]() 
#40252 0x000000011340ff38 in __58-[VKMapCameraController zoom:withPoint:completionHandler:]_block_invoke.132() 
#40253 0x00000001133bcd30 in -[VKAnimation stopAnimation:]() 
#40254 0x00000001133bd0f6 in -[VKTimedAnimation stopAnimation:]() 
#40255 0x00000001133bd1d5 in -[VKTimedAnimation onTimerFired:]() 
#40256 0x00000001133e09e9 in -[VKScreenCanvas animateWithTimestamp:]() 
#40257 0x00000001133e0610 in -[VKScreenCanvas updateWithTimestamp:]() 
#40258 0x000000011339b3dc in -[VKMapView onTimerFired:]() 
#40259 0x00000001137b2c69 in -[GGLDisplayLink _displayLinkFired:]() 
#40260 0x000000010cbffbd5 in CA::Display::DisplayLinkItem::dispatch(unsigned long long)() 
#40261 0x000000010cbffa95 in CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long)() 
#40262 0x000000010f5ed964 in __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__() 
#40263 0x000000010f5ed5f3 in __CFRunLoopDoTimer() 
#40264 0x000000010f5ed17a in __CFRunLoopDoTimers() 
#40265 0x000000010f5e4f01 in __CFRunLoopRun() 
#40266 0x000000010f5e4494 in CFRunLoopRunSpecific() 
#40267 0x0000000112b93a6f in GSEventRunModal() 
#40268 0x000000010ce7ef34 in UIApplicationMain() 
#40269 0x000000010b6af59f in main 

回答

0

的解決結果有沒有關係,雖然地圖包。

請參閱here,它似乎雖然它工作了一段時間,一個對象不應該委託給多個CALayer s。

子類化CALayer並在圖層上實現自定義繪圖最終解決了這個問題。