2017-02-07 10 views
3

В моем приложении у меня есть требование таким образом, что мне нужно заполнить круг красным цветом с процентными значениями, такими как 50%, 80%, которые я получаю от API, как показано ниже.Как заполнить цвет круга по проценту?

enter image description here

В настоящее время я использую следующий код для достижения этой цели.

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)* 

он показывает, как показано ниже

enter image description here

Можете ли вы предложить мне, как это сделать. В настоящее время я сталкиваюсь с проблемой преобразования процента в градусы.

+0

вы можете использовать https://github.com/xyfeng/XYPieChart – raki

+0

Это также хороший контроль, чтобы сделать это: https://github.com/yasuoza/XYDoughnutChart – bisma

+0

раки и Bisma Спасибо для вашего быстрого ответа я не хочу использовать сторонние библиотеки. – lazyCoder

ответ

12

Ваша проблема в том, что вы не рисуете полный путь - одна дуга не сделает этого. Вам нужно запустить путь по центру и нарисовать прямые края сегмента, а также дугу. Здесь он находится на игровой площадке - я старался сохранить как можно больше в вашем стиле, но представил параметры proportion, который является вашим процентом, и startAngle, который является ориентацией сегмента.

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 - добавить текстовую метку

ОР бросил пару изогнутых шаров после того, как мой первоначальный ответ, в том числе ориентируя сегмент (реализованный выше) и мечения сегмент процент, который действительно должен был быть отдельным вопросом, однако, это не необоснованная вещь, которую нужно делать на круговой диаграмме, так что вот ее ...

// 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

Спасибо за быстрый и подробный ответ. Две вещи, о которых я забыл упомянуть в своем вопросе. Q1), кружок должен начинаться сверху, как часы в 12:00, и нужно заполнять часы зеленого цвета. 2Q) Мне нужно добавить lable в круг, который указывает процент. – lazyCoder

+2

Линия от текущей точки до начальной точки дуги по периметру автоматически добавляется 'addArc'. Вторая 'addLine' может быть опущена, если вы явно закрываете путь. –

+0

@MartinR - действительно, но вам нужно либо явно закрыть его, либо косвенно закрыть его! – Grimxn