2014-01-15 1 views
0

나는 현재 아래의 타이머를 사용하여 원형 선 - 카운트 다운 선을 움직입니다. 이 값은 _percent로 전달되는 초 단위로 애니메이션됩니다.UIBezierPath를 사용하는 사용자 정의 타이머 애니메이션

나는 초를 묘사하는 원형 바퀴를 갖고 싶습니다. 그러나 나는 초당 1 초 동안 지속되는 애니메이션을 _percent에 남겨 두는 방법에 고심하고 있습니다. 예 : 백분율이 100이면 원을 1 초 동안 100 번 반복하는 애니메이션을 원합니다. (아래에 표시된 애니메이션 효과를 얻는 것뿐 아니라

여기에 명확성을위한 그림이 나와 있습니다.) 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; 
    } 
} 

을 여기에 내가 매 초마다 왼쪽 1 초를 지속 새로운 원형 애니메이션을 추가 할 내 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

관련 문제