2017-02-07 4 views
3

내 응용 프로그램에서 나는 아래 그림과 같이 API에서 얻는 50 %, 80 %와 같은 백분율 값을 사용하여 붉은 색 원을 채울 필요가있는 요구 사항을 가지고 있습니다.원색을 백분율 값으로 채우는 방법은 무엇입니까?

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

라키 (Raki)와 비스 마 감사합니다 빠른 응답을 위해 제 3 자 라이브러리를 사용하고 싶지 않습니다. – 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 - 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