2014-01-15 15 views
0

我目前有一個計時器,在該計時器下面有一個循環線 - 倒計時線。這根據我傳遞給_percent的秒數進行動畫處理。使用UIBezierPath自定義定時器動畫

我想要另一個圓形的輪子,描繪秒。然而,我正在努力如何在_percent中留下每秒一秒的動畫。例如如果百分比是100,我想圈出100倍持續1秒的動畫循環。 (以及實現如下所示的動畫效果)

這是爲了清晰起見而繪製的圖:) 3的第一行顯示了它當前的樣子,最下面的3行顯示了我想要的效果...... enter image description here

這裏是我激發關閉計時器在我的視圖控制器類:

-(void)viewDidLoad 
{ 
     CPCircleCountdownView *m_testView; 
    m_testView.percent = 100; 
} 

- (IBAction)StartTimerButtonPressed:(id)sender 
{ 
    // Kick off a timer to count it down 
    m_timer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(decrementSpin) userInfo:nil repeats:YES]; 
} 

- (void)decrementSpin 
{ 
    // If we can decrement our percentage, do so, and redraw the view 
    if (m_testView.percent > 0) { 
     m_testView.percent = m_testView.percent - 1; 
     [m_testView setNeedsDisplay]; 
    } 
    else { 
     [m_timer invalidate]; 
     m_timer = nil; 
    } 
} 

,這裏是我的CPCountdownView這裏我想補充新的圓形動畫持續每秒左一秒鐘。理論上的兩個動畫應該同時完成。

#import "CPCircleCountdownView.h" 

@interface CPCircleCountdownView() 
{ 
    CGFloat startAngle; 
    CGFloat endAngle; 
} 

@end 

@implementation CPCircleCountdownView 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code 

     self.backgroundColor = [UIColor clearColor]; 

     //get start and end angles 
     startAngle = M_PI * 1.5; 
     endAngle = startAngle + (M_PI * 2); 
    } 
    return self; 
} 

- (void)drawRect:(CGRect)rect 
{ 
    //Display arc percent 
    //NSString *textContent = [NSString stringWithFormat:@"%d", self.percent]; //TODO: Pass total number of seconds int 

    //------------------------- 
    UIBezierPath* bezierPath = [UIBezierPath bezierPath]; 
    // Create our arc, with the correct angles 
    [bezierPath addArcWithCenter:CGPointMake(rect.size.width/2, rect.size.height/2) 
          radius:130 
         startAngle:startAngle 
         endAngle:(endAngle - startAngle) * (_percent/_overallScore) + startAngle 
         clockwise:YES]; 
    // Set the display for the path, and stroke it 
    bezierPath.lineWidth = 2; 
    [[UIColor colorWithRed:122.0/255.0 green:197.0/255.0 blue:205.0/255.0 alpha:1.0] setStroke]; 
    [bezierPath stroke]; 

    //------------------------- 
} 

任何幫助將是巨大的我是比較新的,所以如果你可以給我的例子,這將是巨大的:)謝謝

回答

0

可能是一個更好的辦法是使用2個CAShapeLayers和動畫貝塞爾路徑。假設CPCircleCountdownView是一個UIView子類

@interface CPCircleCountdownView() 

    @property (nonatomic) CAShapeLayer* layer1; 
    @property (nonatomic) CAShapeLayer* layer2; 
    @property (nonatomic, assign) float startAngle; 
    @property (nonatomic, assign) float endAngle;  
@end 

@implementation CPCircleCountdownView 

- (void)intiWithFrame:(CGRect) Frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     _startAngle = M_PI * 1.5; 
    _endAngle = _startAngle + (M_PI * 2); 

    } 


} 

-(void)layoutSubviews{ 

    self.layer1 = [CAShapeLayer layer]; 
    self.layer1.fillColor = [UIColor clearColor].CGColor; 
    self.layer1.strokeColor = [UIColor redColor].CGColor; 

    self.layer2 = [CAShapeLayer layer]; 
    self.layer2.fillColor = [UIColor clearColor].CGColor; 
    self.layer2.strokeColor = [UIColor greenColor].CGColor; 

    [self.layer1 setFrame:CGRectMake(50, 50, 200, 200)]; 
    [self.layer2 setFrame:CGRectMake(50, 50, 200, 200)]; 
    UIBezierPath *path1 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.layer1.frame.size.width/2, self.layer1.frame.size.height/2) 
                radius:130 
               startAngle:self.startAngle 
                endAngle:self.endAngle 
                clockwise:YES]; 

    UIBezierPath *path2 = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.layer2.frame.size.width/2, self.layer2.frame.size.height/2) 
                radius:125 
               startAngle:self.endAngle 
                endAngle:self.startAngle 
                clockwise:NO]; 

    self.layer1.path = path1.CGPath; 
    self.layer2.path = path2.CGPath; 
    [self.view.layer addSublayer:self.layer1]; 
    [self.view.layer addSublayer:self.layer2]; 
    [self.layer1 setStrokeEnd:1.0f]; 
    [self.layer2 setStrokeEnd:0.0f]; 
    // i've placed this here for convenience in testing, really it should be in method called by your button Action 
    [self decrementSpinForValue:100]; 

} 

- (void)animationDidStop:(CAAnimation *)animation finished:(BOOL)finished { 
    [self.layer1 removeAllAnimations]; 
    [self.layer2 removeAllAnimations]; 
} 


-(void) decrementSpinForValue:(float) percent{ 

    CABasicAnimation *strokeEndAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 
    strokeEndAnimation.delegate = self; 
    strokeEndAnimation.duration = percent; 
    [strokeEndAnimation setFillMode:kCAFillModeForwards]; 
    strokeEndAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
    strokeEndAnimation.removedOnCompletion = NO; 
    strokeEndAnimation.fromValue = [NSNumber numberWithFloat:1.0f]; 
    strokeEndAnimation.toValue = [NSNumber numberWithFloat:0.0f]; 
    [self.layer1 addAnimation:strokeEndAnimation forKey:@"progressOuterStatus"]; 

    CABasicAnimation *strokeEndAnimation2 = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; 
    strokeEndAnimation2.duration = 1.0f; 
    strokeEndAnimation2.repeatCount = percent; 
    [strokeEndAnimation2 setFillMode:kCAFillModeForwards]; 
    strokeEndAnimation2.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
    strokeEndAnimation2.removedOnCompletion = NO; 
    strokeEndAnimation2.fromValue = [NSNumber numberWithFloat:0.0f]; 
    strokeEndAnimation2.toValue = [NSNumber numberWithFloat:1.0f]; 
    [self.layer2 addAnimation:strokeEndAnimation2 forKey:@"progressInnerStatus"]; 


} 

@end 

我認爲這給你一個你如何完成它的想法。

+0

問題是,cabasicanimation在應用程序關閉並再次打開時被刪除。意味着沒有更多的動畫。 – Ryan

+0

足夠簡單,可以添加通知並重新創建最後一次關閉的動畫。 – MDB983