2017-02-07 6 views
3

In meiner Anwendung habe ich eine Anforderung in einer Weise, dass ich Kreis mit roter Farbe mit Prozentwerten wie 50%, 80% füllen muss, die ich von API wie unten Bild bekomme.Wie füllt man eine Kreisfarbe nach Prozentwert?

enter image description here

Derzeit ich den Code unten benutze dies zu erreichen.

let roundView = UIView(frame:CGRect(x: 100, y: 100, width: 250, height: 250)) 
    roundView.backgroundColor = UIColor.white 
    roundView.layer.cornerRadius = roundView.frame.size.width/2 


    // bezier path 
    let circlePath = UIBezierPath(arcCenter: CGPoint (x: roundView.frame.size.width/2, y: roundView.frame.size.height/2), 
            radius: roundView.frame.size.width/2, 
            startAngle:CGFloat(M_PI_2), 
            endAngle: CGFloat (M_PI * 2.0), 
            clockwise: true) 
    circlePath.move(to: roundView.center) 
    // circle shape 
    let circleShape = CAShapeLayer() 
    circleShape.path = circlePath.cgPath 
    circleShape.strokeColor = UIColor.black.cgColor 
    circleShape.fillColor = UIColor.green.cgColor 
    circleShape.lineWidth = 1.5   
    // add sublayer 
    roundView.layer.addSublayer(circleShape) 
    // add subview 
    self.view.addSubview(roundView)* 

es zeigt wie unter

enter image description here

Können Sie mir bitte vorschlagen, wie dies zu tun. Zur Zeit habe ich Probleme, den Prozentsatz in Grad umzurechnen.

+0

können Sie https://github.com/xyfeng/XYPieChart verwenden – raki

+0

Dies ist auch eine gute Kontrolle, dies zu tun: https://github.com/yasuoza/XYDoughnutChart – bisma

+0

Raki und Bisma Dank Für Ihre schnelle Antwort möchte ich keine Bibliotheken von Drittanbietern verwenden. – lazyCoder

Antwort

12

Ihr Problem ist, dass Sie nicht den vollständigen Pfad zeichnen - ein Bogen allein wird es nicht tun. Sie müssen den Pfad in der Mitte beginnen und die geraden Kanten des Segments sowie den Bogen zeichnen. Hier ist es in Spielplatz - Ich habe versucht, so viel wie möglich zu Ihrem Stil zu halten, aber haben die Parameter proportion, die Ihren Prozentsatz ist, und startAngle, die die Ausrichtung des Segments ist eingeführt.

import UIKit 
let roundView = UIView(frame:CGRect(x: 100, y: 100, width: 250, height: 250)) 
roundView.backgroundColor = UIColor.white 
roundView.layer.cornerRadius = roundView.frame.size.width/2 

// vary this to move the start of the arc 
let startAngle = -CGFloat.pi/2 // This corresponds to 12 0'clock 
// vary this to vary the size of the segment, in per cent 
let proportion = CGFloat(80) 
let centre = CGPoint (x: roundView.frame.size.width/2, y: roundView.frame.size.height/2) 
let radius = roundView.frame.size.width/2 
let arc = CGFloat.pi * 2 * proportion/100 // i.e. the proportion of a full circle 

// Start a mutable path 
let cPath = UIBezierPath() 
// Move to the centre 
cPath.move(to: centre) 
// Draw a line to the circumference 
cPath.addLine(to: CGPoint(x: centre.x + radius * cos(startAngle), y: centre.y + radius * sin(startAngle))) 
// NOW draw the arc 
cPath.addArc(withCenter: centre, radius: radius, startAngle: startAngle, endAngle: arc + startAngle, clockwise: true) 
// Line back to the centre, where we started (or the stroke doesn't work, though the fill does) 
cPath.addLine(to: CGPoint(x: centre.x, y: centre.y)) 
// n.b. as @MartinR points out `cPath.close()` does the same! 

// circle shape 
let circleShape = CAShapeLayer() 
circleShape.path = cPath.cgPath 
circleShape.strokeColor = UIColor.black.cgColor 
circleShape.fillColor = UIColor.green.cgColor 
circleShape.lineWidth = 1.5 
// add sublayer 
roundView.layer.addSublayer(circleShape) 
roundView 

enter image description here

Bonus - fügen Sie einen Text-Label

Die OP warf ein paar gebogene Bälle nach meiner ersten Antwort, einschließlich des Segments Orientieren (implementiert oben) und die Kennzeichnung des Segments mit der Prozentsatz, der wirklich sollte eine separate Frage gewesen sein, jedoch ist es nicht eine unangemessene Sache, auf einem Kreisdiagramm zu tun, so hier ist es ...

// Bonus - add text layer 
// choose your font 
let fontSize = CGFloat(20) 
let font = UIFont.systemFont(ofSize: fontSize) 
let attributes = [NSFontAttributeName: font] 
// Format the string 
let str = String(format: "%3.0f%%", proportion) 
// Calculate the text size 
let textSize = str.size(attributes: attributes) 

// Assume the centre of the text is half way along the bisector of the segment 
let halfAngle = startAngle + arc/2 
let centreText = CGPoint(x: centre.x + radius * cos(halfAngle)/2, y: centre.y + radius * sin(halfAngle)/2) 
// calculate the the lower left of the label given the size 
let originText = CGPoint(x: centreText.x - textSize.width/2, y: centreText.y - textSize.height/2) 
// Allocate the text layer 
let label = CATextLayer() 
label.font = font 
label.fontSize = fontSize 
label.frame = CGRect(origin: originText, size: textSize) 
label.string = str 
label.alignmentMode = kCAAlignmentCenter 
label.foregroundColor = UIColor.black.cgColor 
roundView.layer.addSublayer(label) 
roundView 

enter image description here

+0

Vielen Dank für Ihre schnelle und detaillierte Antwort. Zwei Dinge habe ich in meiner Frage vergessen zu erwähnen. Q1) Der Kreis sollte von oben wie 12:00 Uhr beginnen und muss im Uhrzeigersinn grün gefüllt werden. 2Q) Ich muss ein Etikett in der Kreisansicht hinzufügen, das den Prozentsatz angibt. – lazyCoder

+2

Eine Linie vom aktuellen Punkt zum Anfangspunkt des Bogens am Umfang wird automatisch von 'addArc' hinzugefügt. Die zweite 'addLine' kann entfallen, wenn Sie den Pfad explizit' schließen'. –

+0

@MartinR - in der Tat, aber Sie müssen es entweder explizit schließen oder implizit schließen! – Grimxn

Verwandte Themen