2016-10-20 5 views
0

Я пытаюсь нарисовать круговую диаграмму с массивом сегментов и изображение в центре каждого фрагмента, я нарисовал круговую диаграмму, но не смог добавить изображение в cashapelayer . Я ссылался на следующий пост Swift: Add image to CAShapeLayer, но это не решило мою проблему.Добавление изображения в CAShapeLayer Swift 3

Это то, что я пробовал.

override func draw(_ rect: CGRect) { 
     //let context = UIGraphicsGetCurrentContext() 
     let radius = min(frame.size.width,frame.size.height) * 0.5; 
     let viewCenter = CGPoint(x: frame.size.width * 0.5, y: frame.size.height * 0.5) 
     let valueCount = segments.reduce(0){ $0 + $1.value} 
     var startAngle = -CGFloat(M_PI/2) 

     for segment in segments { 
      let endAngle = startAngle + CGFloat(M_PI * 2) * (segment.value)/valueCount 

      /*context?.move(to: CGPoint(x: viewCenter.x, y: viewCenter.y)) 
      context?.setFillColor(segment.color.cgColor) 
      context?.setStrokeColor(UIColor.black.cgColor) 
      context?.setLineWidth(3.0) 
      context?.addArc(center: viewCenter, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false) 
      context?.fillPath()*/ 

      let pieSliceLayer = CAShapeLayer() 
      let slicePath = UIBezierPath(arcCenter: viewCenter, radius: radius, startAngle: startAngle, endAngle: endAngle, clockwise: false) 
      pieSliceLayer.path = slicePath.cgPath 
      pieSliceLayer.fillColor = segment.color.cgColor 
      self.layer.addSublayer(pieSliceLayer) 

      let halfAngle = startAngle + (endAngle - startAngle) * 0.5; 
      let imagePositionValue = CGFloat(0.67) 
      let segmentCenter = CGPoint(x:viewCenter.x+radius*imagePositionValue*cos(halfAngle),y:viewCenter.y+radius*imagePositionValue*sin(halfAngle)) 

      //If image is associated , add the image to the section 
      let imageLayer = CAShapeLayer() 
      let image = UIImage(named: segment.imageName) 
      imageLayer.contents = image?.ciImage 
      imageLayer.frame = CGRect(x: segmentCenter.x - 20, y: segmentCenter.y - 20, width: 20, height: 20) 
      self.layer.addSublayer(imageLayer) 
      startAngle = endAngle 

     } 
    } 

Я пытался что-то подобное в Objective-C и она отлично работает,

CALayer *imageLayer = (CALayer *)[[pieLayer sublayers] objectAtIndex:0]; 
    //Adding image 
    CALayer *layer = [CALayer layer]; 
    layer.backgroundColor = [[UIColor clearColor] CGColor]; 
    layer.bounds = CGRectMake(imageLayer.bounds.origin.x +20 , 
            imageLayer.bounds.origin.y + 20, 15, 15); 
    NSString *imageName = [NSString stringWithString:[[self.goalSettingsModel objectAtIndex:value] valueForKeyPath:@"imageName"]]; 
    layer.contents = (id)[UIImage imageNamed:imageName].CGImage; 
    [imageLayer addSublayer:layer]; 
    [imageLayer setNeedsDisplay]; 

Я не уверен, если я пропустил какие-либо настройки для CALayer.

+0

Привет пытался делать это так же, как цели - с сниппета, чтобы вычислить центр дуги путь Я использую следующий код, я до сих пор не вижу изображения, пусть boundingBox = pieSliceLayer.path? .boundingBox let centerPoint = CGPoint (x: (boundingBox? .origin.x)! + (boundingBox? .size.width)!/2, y: (boundingBox? .origin.y)! + (BoundingBox? .size.height)!/2) –

ответ

1

После установки атрибута позиции для слоя, изображение было правильно добавлен к слою формы,

let imageLayer = CALayer() 
     imageLayer.backgroundColor = UIColor.clear.cgColor 
     imageLayer.bounds = CGRect(x: centerPoint.x, y: centerPoint.y , width: 15, height: 15) 
     imageLayer.position = CGPoint(x:centerPoint.x ,y:centerPoint.y) 
      imageLayer.contents = UIImage(named:segment.imageName)?.cgImage 
     self.layer.addSublayer(pieSliceLayer) 
     self.layer.addSublayer(imageLayer) 
0

Пара вещей:

Во-первых, вам нужно только обновить слой формы, когда меняется график (вызов setNeedsDisplay) или когда у вас есть изменения макета (viewDidLayoutSubviews). Вам не нужно реализовывать drawRect, если вы не собираетесь делать рисунок. Система наслаивания известна как визуализировать слой формы и будет отображать его по мере необходимости.

Во-вторых, CAShapeLayer предназначен для фигур. На самом деле есть целая куча CALayers, и все они рисуют разные вещи: https://www.raywenderlich.com/90919/great-calayer-tour-tech-talk-video. В случае простого старого изображения просто сделайте то, что делает ваш код Objective C, и используйте отдельный CALayer для хранения изображения вместо CAShapeLayer. Добавьте свой слой изображения в качестве подслоя поверх или позади слоя формы графика, в зависимости от вашего предпочтения z-порядка.

+0

Спасибо за видео-ссылку, это было очень полезно. Я исправил проблему, установив положение CALayer. let imageLayer = CALayer() imageLayer.backgroundColor = UIColor.clear.cgColor imageLayer.bounds = CGRect (x: centerPoint.x, y: centerPoint.y, width: 15, height: 15) imageLayer.position = CGPoint (x: centerPoint.x, y: centerPoint.y) imageLayer.contents = UIImage (named: segment.imageName) ?. cgImage self.layer.addSublayer (pieSliceLayer) self.layer.addSublayer (imageLayer) –