7

UIView 하위 클래스에서 UIBeizerPath (내 예제에서는 삼각형)의 드로잉에 애니메이션을 적용하려고합니다. 그러나 전체 하위 뷰는 모양 대신 애니메이션으로 표시됩니다.CoreGraphics를 그리는 방법 CAKeyframeAnimation을 사용하여 도형 그리기

애니메이션이 누락 되었습니까?

- (void)drawRect:(CGRect)rect { 

    CAShapeLayer *drawLayer = [CAShapeLayer layer]; 

    drawLayer.frame   = CGRectMake(0, 0, 100, 100); 
    drawLayer.strokeColor  = [UIColor greenColor].CGColor; 
    drawLayer.lineWidth  = 4.0; 

    [self.layer addSublayer:drawLayer]; 

    UIBezierPath *path = [UIBezierPath bezierPath]; 

    [path moveToPoint:CGPointMake(0,0)]; 
    [path addLineToPoint:CGPointMake(50,100)]; 
    [path addLineToPoint:CGPointMake(100,0)]; 
    [path closePath]; 

    CGPoint center = [self convertPoint:self.center fromView:nil]; 

    [path applyTransform:CGAffineTransformMakeTranslation(center.x, center.y)]; 

    [[UIColor redColor] set]; 

    [path fill]; 

    [[UIColor blueColor] setStroke]; 

    path.lineWidth = 3.0f; 

    [path stroke]; 

    CAKeyframeAnimation *pathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"]; 

    pathAnimation.duration  = 4.0f; 
    pathAnimation.path   = path.CGPath; 
    pathAnimation.calculationMode = kCAAnimationLinear; 

    [drawLayer addAnimation:pathAnimation forKey:@"position"]; 
} 
+0

수단 "는 UIBezierPath의 드로잉 애니메이션"정확히 설명한다. 당신은 개별 세그먼트를 차례로 그리기를 원합니 까? –

+0

@kurt yes 삼각형이 움직이는 것처럼 보이도록 각 점의 그림을 애니메이션화하려고합니다. –

답변

17
  • 당신은 CAShapeLayer를 작성하지만, 다음과 유용한 작업을 수행하지 않는. 그것을 수정합시다.

  • -drawRect:에 레이어와 애니메이션을 설정하지 마십시오. CoreGraphics 또는 UIKit API를 사용하여 그림을 그리는 시간을 의미하기 때문에. 대신, CAShapeLayer가 삼각형을 그려야합니다. 그러면 삼각형을 움직일 수 있습니다.

  • CAKeyframeAnimation.path는 완전히 다른 것으로 (예 : 경로를 따라 레이어 이동) 의미합니다.

  • 애니메이션이 레이어의 값인 position에 애니메이션을 적용하고 있습니다. 그것이 레이어를 움직이는 것은 놀라운 일이 아닙니다! 대신 path 값에 애니메이션을 적용하려고합니다.

  • CAKeyframeAnimation의 배경은 레이어의 속성을 설정할 values의 배열을 제공한다는 것입니다. 키 프레임 사이의 시간 동안 두 개의 인접한 키 프레임 사이를 보간합니다. 따라서 각면에 하나씩 여러 경로를 지정해야합니다.

  • 임의 경로를 보간하는 것은 어렵습니다. CA의 경로 보간은 경로의 요소 수와 유형이 같을 때 가장 효과적입니다. 그래서 우리는 모든 경로가 같은 구조를 유지하는지 확인합니다.

  • 애니메이션에 대한 비법 및 일반적으로 컴퓨터에 대한 것 : 해야합니다. "각 지점의 그림을 애니메이션으로 만들고 싶기 때문에 움직이는 것처럼 보입니다"라는 정보는 충분하지 않습니다.

는 여기에 내가 당신이 요구하는, 또는 적어도 가까운하는지 않습니다 생각 UIView의 서브 클래스입니다. 애니메이션을 적용하려면 버튼을 -animate: 동작까지 연결합니다.

SPAnimatedShapeView.h :

#import <UIKit/UIKit.h> 

@interface SPAnimatedShapeView : UIView 

- (IBAction)animate:(id)sender; 

@end 

SPAnimatedShapeView.m :

#import "SPAnimatedShapeView.h" 
#import <QuartzCore/QuartzCore.h> 

@interface SPAnimatedShapeView() 
@property (nonatomic, retain) CAShapeLayer* shapeLayer; 
@end 

@implementation SPAnimatedShapeView 

@synthesize shapeLayer = _shapeLayer; 

- (void)dealloc 
{ 
    [_shapeLayer release]; 
    [super dealloc]; 
} 

- (void)layoutSubviews 
{ 
    if (!self.shapeLayer) 
    { 
     self.shapeLayer = [[[CAShapeLayer alloc] init] autorelease]; 
     self.shapeLayer.bounds = CGRectMake(0, 0, 100, 100);  // layer is 100x100 in size 
     self.shapeLayer.position = self.center;     // and is centered in the view 
     self.shapeLayer.strokeColor = [UIColor blueColor].CGColor; 
     self.shapeLayer.fillColor = [UIColor redColor].CGColor; 
     self.shapeLayer.lineWidth = 3.f; 

     [self.layer addSublayer:self.shapeLayer]; 
    } 
} 

- (IBAction)animate:(id)sender 
{ 
    UIBezierPath* path0 = [UIBezierPath bezierPath]; 
    [path0 moveToPoint:CGPointZero]; 
    [path0 addLineToPoint:CGPointZero]; 
    [path0 addLineToPoint:CGPointZero]; 
    [path0 addLineToPoint:CGPointZero]; 

    UIBezierPath* path1 = [UIBezierPath bezierPath]; 
    [path1 moveToPoint:CGPointZero]; 
    [path1 addLineToPoint:CGPointMake(50,100)]; 
    [path1 addLineToPoint:CGPointMake(50,100)]; 
    [path1 addLineToPoint:CGPointMake(50,100)]; 

    UIBezierPath* path2 = [UIBezierPath bezierPath]; 
    [path2 moveToPoint:CGPointZero]; 
    [path2 addLineToPoint:CGPointMake(50,100)]; 
    [path2 addLineToPoint:CGPointMake(100,0)]; 
    [path2 addLineToPoint:CGPointMake(100,0)]; 

    UIBezierPath* path3 = [UIBezierPath bezierPath]; 
    [path3 moveToPoint:CGPointZero]; 
    [path3 addLineToPoint:CGPointMake(50,100)]; 
    [path3 addLineToPoint:CGPointMake(100,0)]; 
    [path3 addLineToPoint:CGPointZero]; 

    CAKeyframeAnimation* animation = [CAKeyframeAnimation animationWithKeyPath:@"path"];  
    animation.duration = 4.0f; 
    animation.values = [NSArray arrayWithObjects:(id)path0.CGPath, (id)path1.CGPath, (id)path2.CGPath, (id)path3.CGPath, nil]; 
    [self.shapeLayer addAnimation:animation forKey:nil]; 
} 

@end 
+0

설명해 주셔서 감사합니다. 이것은 정말로 도움이됩니다. –

+5

더 쉬운 방법이 있습니다 : 0에서 1까지의 'CABasicAnimation'을 사용하여'strokeEnd' 속성을 애니메이트하십시오. [설명과 샘플 코드는 여기에 있습니다] (http://oleb.net/blog/2010/12/animating-drawing -of-cgpath-with-cashapelayer /). –