2010-11-25 7 views
12

화면 둘레를 움직이는 두 개의 원이 있습니다. 원은 다른 UIView가 포함 된 두 UIView입니다. 각 원 밖에있는 영역은 투명합니다.코어 애니메이션 애니메이션 추적

두 개의 원을 사변형으로 연결하는 CGPath를 작성하는 함수를 작성했습니다. 전체 화면에 걸쳐있는 투명 CALayer에서이 경로를 채 웁니다. 이 레이어는 두 개의 원형 UIView 뒤에 있으므로 연결하는 것처럼 보입니다.

마지막으로, 두 UIView는 Core Animation을 사용하여 애니메이션됩니다. 이 애니메이션 중에 두 원의 위치와 크기이 변경됩니다.

지금까지 내가 어떤 성공을 가지고있는 유일한 방법은 다음에, NSTimer를 사용하여 일정한 간격으로 애니메이션을 중단 다시 계산하고 원의 표현 계층의 위치에 따라 빔을 그릴 것입니다. 그러나 사각형이 인 경우 애니메이션 속도가 올라가면 개의 서클에 비해 뒤떨어집니다.

Core Animation을 사용하여 더 좋은 방법이 있습니까? 아니면 코어 애니메이션을 피하고 NSTimer를 사용하여 내 애니메이션을 구현해야합니까?

답변

12

비슷한 문제가 발생했습니다. 나는 애니메이션 대신 뷰를 사용했다. 이런 식으로해볼 수 있습니다.

  1. 각 요소를 CALayer로 그려서 컨테이너 UIVIew의 하위 레이어로 포함시킵니다. UIView는 애니메이션을 적용하는 것이 더 쉽지만 제어가 덜합니다. 어떤 뷰에서도 [view layer]로 레이어를 얻을 수 있습니다.
  2. 사변형에 대한 사용자 지정 하위 계층을 만듭니다. 이 레이어에는이 레이어에 대해 애니메이트하려는 속성 또는 여러 속성이 있어야합니다. 이 속성을 "customprop"이라고 부르 자. 사용자 정의 레이어이기 때문에 애니메이션의 각 프레임을 다시 그리기를 원합니다. 애니메이션을 적용하려는 속성의 경우 맞춤 레이어 클래스는 YES needsDisplayForKey :를 반환해야합니다. 당신이 보장하는 그런 식으로 - (void) drawInContext : (CGContextRef) theContext은 모든 프레임에서 호출됩니다.
  3. 모든 애니메이션 (동그라미와 쿼드 모두)을 동일한 트랜잭션에 넣습니다. 쿼드 레이어 지금

    layer.contents = [UIImage imageNamed:@"circle_image.png"].CGImage; 
    

    , 서브 클래스의 CALayer 및 구현 : 당신은 아마 CALayers를 사용하고,이 이미지 인 경우, 표준 방법의 내용을 설정할 수있는 원 대한


이 방법 :

:

- (void)drawInContext:(CGContextRef)theContext{ 
    //Custom draw code here 
} 
+ (BOOL)needsDisplayForKey:(NSString *)key{ 
    if ([key isEqualToString:@"customprop"]) 
     return YES; 
    return [super needsDisplayForKey:key]; 
} 

는 트랜잭션의 모습

[CATransaction begin]; 
CABasicAnimation *theAnimation=[CABasicAnimation animationWithKeyPath:@"customprop"]; 

theAnimation.toValue = [NSValue valueWithCGPoint:CGPointMake(1000, 1000)]; 
theAnimation.duration=1.0; 
theAnimation.repeatCount=4; 
theAnimation.autoreverses=YES; 
theAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 
theAnimation.delegate = self; 
[lay addAnimation:theAnimation forKey:@"selecting"]; 

[CATransaction setValue:[NSNumber numberWithFloat:10.0f] 
        forKey:kCATransactionAnimationDuration]; 
circ1.position=CGPointMake(1000, 1000); 
circ2.position=CGPointMake(1000, 1000); 
[CATransaction commit]; 

이제 모든 그리기 루틴이 동시에 발생합니다. drawInContext : 구현이 빠르다는 것을 확인하십시오. 그렇지 않으면 애니메이션이 지연됩니다.

각 하위 레이어를 UIViews 레이어에 추가 한 후 [레이어 setNeedsDisplay]를 호출하도록 기억하십시오. 자동으로 호출되지 않습니다.

나는 이것이 약간 복잡하다는 것을 알고있다. 그러나 결과 애니메이션은 NSTimer를 사용하고 각 호출에서 다시 그리는 것보다 낫습니다.

+0

커스텀 프로퍼티를 사용하는 대신 완전한 프로그래밍 방식의 애니메이션을 구현하고자하는 사람들을위한 참고 사항 : 'NSTimer'를 사용하지 마십시오. 느리고 CPU 욕심이 듭니다. 애니메이션과 관련된 모든 작업은 화면 새로 고침 빈도와 동기화되고 CoreAnimation에서 내부적으로 사용되는 ['CADisplayLink'] (https://developer.apple.com/library/ios/documentation/QuartzCore/Reference/CADisplayLink_ClassRef/)를 사용하십시오 . – skozin

1

레이어의 현재 표시 상태를 찾으려면 해당 CALayer에서 -presentationLayer을 호출하면 렌더링에 사용 된 레이어와 비슷한 레이어가 표시됩니다. 나는 근사값을 말했어 - 완전히 정확하다는 보장은 없다. 그러나 그것은 당신의 목적을 위해 충분히 좋을 수도 있습니다.

+0

앞서 언급했듯이 이미 presentationLayer를 사용해 보았지만 서클 뒤에 뒤처져 있습니다. 여러 구성 요소의 애니메이션을보다 안정적으로 동기화하는 방법이 필요합니다. – titaniumdecoy

+0

제가 믿을 수있는 유일한 방법은 애니메이션 기계를 연결하는 것입니다. CAShapeLayer를 사용하고 서클과 동기화 된 경로를 애니메이션으로 볼 수 있습니다. –

관련 문제