2010-09-16 93 views
25

對於iPhone應用程序,我想繪製一個圓圈,即只填充x個百分比。繪製圓的一部分

事情是這樣的:

alt text

我沒有問題計算半徑,度數,弧度,這是沒有問題的。另外畫圓也已經完成了。但是,如何讓iPhone SDK繪製填充的部分。

我可以繪製一個長方形的大小,但不是圓的一部分。

我只是想在正常情況下繪製。

希望有人能在這裏給我任何指針。

回答

20

使用CGContext的弧功能:

CGContextAddArc(context, 
       centerX, 
       centerY, 
       radius, 
       startAngleRadians, 
       endAngleRadians, 
       clockwise ? 1 : 0);  

查看文檔CGContextAddArc()

+3

這很容易修復。只需在之前的行中添加'CGContextMoveToPoint(context,centerX,centerY);'。 – 2013-04-12 23:24:59

8

試試這個:

CGContextMoveToPoint(the center point) 
CGContextAddLineToPoint(the starting point of the fill path on the circumference) 
CGContextAddArcToPoint(the ending point of the fill path on the circumference) 
CGContextAddLineToPoint(the center point) 
CGContextFillPath 
6

我實施了類似於你在做什麼餡餅進度視圖。它是開源的。希望源代碼將有所幫助。

SSPieProgressView.h source

SSPieProgressView.m source

+0

感謝您的支持!這是該帖子的最佳答案,因此+1。真的很好,簡潔的代碼。真的很感謝你把它放在GitHub上。謝謝! – 2012-04-07 19:17:43

45

很多人都表現出你如何能核芯顯卡來完成,但它也可以與核心動畫這給大除了很容易能夠動畫的完成餡餅形狀的百分比。

下面的代碼將創建環和部分填充的圖層(即使您說你已經可以繪製圓環),因爲它很好地使用相同的方法繪製圓環和餅圖形狀。

如果將pieShape圖層的strokeStartstrokeEnd屬性製作爲動畫,則將使動畫百分比變爲百分比。與所有Core Animation代碼一樣,您需要將QuartzCore.framework添加到您的項目中,並在代碼中包含<QuartzCore/QuartzCore.h>

// Create a white ring that fills the entire frame and is 2 points wide. 
// Its frame is inset 1 point to fit for the 2 point stroke width 
CGFloat radius = MIN(self.frame.size.width,self.frame.size.height)/2; 
CGFloat inset = 1; 
CAShapeLayer *ring = [CAShapeLayer layer]; 
ring.path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(self.bounds, inset, inset) 
             cornerRadius:radius-inset].CGPath; 

ring.fillColor = [UIColor clearColor].CGColor; 
ring.strokeColor = [UIColor whiteColor].CGColor; 
ring.lineWidth = 2; 

// Create a white pie-chart-like shape inside the white ring (above). 
// The outside of the shape should be inside the ring, therefore the 
// frame needs to be inset radius/2 (for its outside to be on 
// the outside of the ring) + 2 (to be 2 points in). 
CAShapeLayer *pieShape = [CAShapeLayer layer]; 
inset = radius/2 + 2; // The inset is updated here 
pieShape.path = [UIBezierPath bezierPathWithRoundedRect:CGRectInset(self.bounds, inset, inset) 
             cornerRadius:radius-inset].CGPath; 
pieShape.fillColor = [UIColor clearColor].CGColor; 
pieShape.strokeColor = [UIColor whiteColor].CGColor; 
pieShape.lineWidth = (radius-inset)*2; 

// Add sublayers 
// NOTE: the following code is used in a UIView subclass (thus self is a view) 
// If you instead chose to use this code in a view controller you should instead 
// use self.view.layer to access the view of your view controller. 
[self.layer addSublayer:ring]; 
[self.layer addSublayer:pieShape]; 
+4

這是一個很好的答案。 – zekel 2012-10-12 17:20:36

+1

下面是這個strokeStart的動畫(或者您可以使用strokeEnd): CABasicAnimation *pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; pathAnimation.duration = 3.0; pathAnimation.fromValue = [NSNumber numberWithFloat:0.0f]; pathAnimation.toValue = [NSNumber numberWithFloat:0.3f]; pathAnimation.removedOnCompletion = NO; pathAnimation.fillMode = kCAFillModeForwards; [pieShape addAnimation:pathAnimation forKey:@"strokeEndAnimation"]; cynistersix 2014-01-27 02:48:59

0

下面是我使用的一個完整的方法,用Core Graphics對此進行了修改,並對上面的mharper的註釋進行了修改和擴展。

此代碼適用於OSX Cocoa,但可以通過修改獲取上下文的方式輕鬆更改爲iOS。

- (void)drawPieShapedCircleWithRadius:(CGFloat)radius 
         strokeColor:(CGColorRef)strokeColor 
         fillColor:(CGColorRef)fillColor 
         lineWidth:(CGFloat)lineWidth 
        currentDegrees:(float)currentDegrees 
        startDegrees:(float)startDegrees { 
    // get the context 
    CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; 

    // Set the color of the circle stroke and fill 
    CGContextSetStrokeColorWithColor(context, strokeColor); 
    CGContextSetFillColorWithColor(context, fillColor); 

    // Set the line width of the circle 
    CGContextSetLineWidth(context, 1); 

    // Calculate the middle of the circle 
    CGPoint circleCenter = CGPointMake(self.frame.size.width/2, self.frame.size.height/2); 

    // Move the bezier to the center of the circle 
    CGContextMoveToPoint(context, circleCenter.x, circleCenter.y); // move to the center point 

    // Draw the arc from the start point (hardcoded as the bottom of the circle) to the center 
    CGContextAddLineToPoint(context, circleCenter.x, circleCenter.y + radius); 

    // Draw the arc around the circle from the start degrees point to the current degrees point 
    CGContextAddArc(context, circleCenter.x , circleCenter.y, radius, [self radians:startDegrees], [self radians:startDegrees + currentDegrees], 0); 

    // Draw the line back into the center of the circle 
    CGContextAddLineToPoint(context, circleCenter.x, circleCenter.y); 

    // Fill the circle 
    CGContextFillPath(context); 

    // Draw the line around the circle 
    CGContextStrokePath(context); 
} 
0

在UIViewController

MyChartClass *myChartClass=[[MyChartClass alloc]initWithFrame:CGRectMake(0, 0, 200, 200)]; 
myChartClass.backgroundColor = [UIColor clearColor]; 
myChartClass.itemArray=[[NSArray alloc]initWithObjects:@"75",@"25", nil]; 
myChartClass.myColorArray=[[NSArray alloc]initWithObjects:[UIColor blackColor],[UIColor whiteColor], nil]; 
myChartClass.radius=100; 
[self.view addSubview:myChartClass]; 

問候試試這個代碼在一個UIView,示例 「MyChartClass」 ......

- (void)drawRect:(CGRect)rect { 
    int c=(int)[itemArray count]; 

    CGFloat angleArray[c]; 
    CGFloat offset; 
    int sum=0; 

    CGContextRef context = UIGraphicsGetCurrentContext(); 

    CGContextSetAllowsAntialiasing(context, false); 
    CGContextSetShouldAntialias(context, false); 

    for(int i=0;i<[itemArray count];i++) { 
     sum+=[[itemArray objectAtIndex:i] intValue]; 
    } 

    for(int i=0;i<[itemArray count];i++) { 
     angleArray[i]=(float)(([[itemArray objectAtIndex:i] intValue])/(float)sum)*(2*3.14); 
     CGContextMoveToPoint(context, radius, radius); 
     if(i==0) 
      CGContextAddArc(context, radius, radius, radius, 0,angleArray[i], 0); 
     else 
      CGContextAddArc(context, radius, radius, radius,offset,offset+angleArray[i], 0); 
     offset+=angleArray[i]; 

     CGContextSetFillColorWithColor(context, ((UIColor *)[myColorArray objectAtIndex:i]).CGColor); 
     CGContextClosePath(context); 
     CGContextFillPath(context); 

    } 
} 

實現。

1

那麼,既然沒有人使用NSBezierPath到目前爲止,我想我可以提供我最近使用了同樣的問題的解決方案:

-(void)drawRect:(NSRect)dirtyRect 
{ 
    double start = -10.0; //degrees 
    double end = 190.0; //degrees 
    NSPoint center = NSMakePoint(350, 200); 
    double radius = 50; 

    NSBezierPath *sector = [NSBezierPath bezierPath]; 
    [sector moveToPoint:center]; 
    [sector appendBezierPathWithArcWithCenter:center radius:radius startAngle:start endAngle:end]; 
    [sector lineToPoint:center]; 
    [sector fill]; 
} 
2

CircleViewController.h

#import <UIKit/UIKit.h> 

@interface CircleViewController : UIViewController 

@end 

CircleViewController。 m

#import "CircleViewController.h" 
#import "GraphView.h" 

@interface CircleViewController() 

@end 

@implementation CircleViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 

    GraphView *graphView = [[GraphView alloc] initWithFrame:CGRectMake(100, 100, 200, 200)]; 
    graphView.backgroundColor = [UIColor whiteColor]; 
    graphView.layer.borderColor = [UIColor redColor].CGColor; 
    graphView.layer.borderWidth = 1.0f; 

    [self.view addSubview:graphView]; 
} 

- (void)didReceiveMemoryWarning { 
    [super didReceiveMemoryWarning]; 
    // Dispose of any resources that can be recreated. 
} 

@end 

GraphView.h

#import <UIKit/UIKit.h> 

@interface GraphView : UIView 

@end 

GraphView.m

#import "GraphView.h" 

@implementation GraphView 

- (void)drawRect:(CGRect)rect { 

    CGPoint circleCenter = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2); 

    [self drawCircleWithCircleCenter:(CGPoint) circleCenter radius:80 firstColor:[UIColor blueColor].CGColor secondeColor:[UIColor redColor].CGColor lineWidth:2 startDegree:0 currentDegree:90]; 
    //[self drawCircleWithCircleCenter2:(CGPoint) circleCenter radius:80 firstColor:[UIColor blueColor].CGColor secondeColor:[UIColor redColor].CGColor lineWidth:2 startDegree:0 currentDegree:90]; 
} 

- (void)drawCircleWithCircleCenter:(CGPoint) circleCenter 
          radius:(CGFloat)radius 
          firstColor:(CGColorRef)firstColor 
          secondeColor:(CGColorRef)secondeColor 
          lineWidth:(CGFloat)lineWidth 
          startDegree:(float)startDegree 
          currentDegree:(float)endDegree { 

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSetLineWidth(context, lineWidth); 

    CGContextMoveToPoint(context, circleCenter.x, circleCenter.y); 

    CGContextAddArc(context, circleCenter.x , circleCenter.y, radius, [self radians:startDegree], [self radians:endDegree], 0); 
    CGContextSetFillColorWithColor(context, firstColor); 
    CGContextFillPath(context); 

    CGContextMoveToPoint(context, circleCenter.x, circleCenter.y); 

    CGContextAddArc(context, circleCenter.x, circleCenter.y, radius, [self radians:endDegree], [self radians:startDegree], 0); 
    CGContextSetFillColorWithColor(context, secondeColor); 
    CGContextFillPath(context); 
} 

- (void)drawCircleWithCircleCenter2:(CGPoint) circleCenter 
          radius:(CGFloat)radius 
         firstColor:(CGColorRef)firstColor 
         secondeColor:(CGColorRef)secondeColor 
         lineWidth:(CGFloat)lineWidth 
         startDegree:(float)startDegree 
        currentDegree:(float)endDegree { 

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSetLineWidth(context, lineWidth); 

    CGContextMoveToPoint(context, circleCenter.x, circleCenter.y); 

    CGContextAddArc(context, circleCenter.x , circleCenter.y, radius, [self radians:startDegree], [self radians:endDegree], 0); 
    CGContextSetFillColorWithColor(context, firstColor); 
    CGContextFillPath(context); 

    CGContextMoveToPoint(context, circleCenter.x, circleCenter.y); 

    CGContextAddArc(context, circleCenter.x, circleCenter.y, radius, [self radians:endDegree], [self radians:startDegree], 0); 
    CGContextSetStrokeColorWithColor(context, secondeColor); 
    CGContextStrokePath(context); 
} 

-(float) radians:(double) degrees { 
    return degrees * M_PI/180; 
} 


@end 

注意:您可以使用的兩種方法之一: 「drawCircleWithCircleCenter」 或 「drawCircleWithCircleCenter2」

這段代碼如果你w螞蟻2個部分分裂細胞只

,如果你想在2層以上的部分分裂的細胞,你可以檢查此:「Drawing a circle ,filled different parts with different color」,檢查答案開始與這句話:「我們有6類」