2010-05-23 4 views
14

CGRect를 fromValue에 전달하는 객체로 변환해야 할 것 같습니까? CABasicAnimation으로 레이어의 프레임에 애니메이션을 적용하는 방법은 무엇입니까?

내가 그것을 시도하는 방법이지만, 그것은 작동하지 않습니다

CABasicAnimation *frameAnimation = [CABasicAnimation animationWithKeyPath:@"frame"]; 
frameAnimation.duration = 2.5; 
frameAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
frameAnimation.fromValue = [NSValue valueWithCGRect:myLayer.frame]; 
frameAnimation.toValue = [NSValue valueWithCGRect:theNewFrameRect]; 
[myLayer addAnimation:frameAnimation forKey:@"MLC"]; 

답변

-6

를 내가이 일을 당신이 할 수있는 마지막 라인을 변경해야 할 것 같아요 :

[myLayer addAnimation:frameAnimation forKey:@"frame"]; 

또한 설정할 수 있습니다 의 CALayer의에서

CABasicAnimation *frameAnimation = [CABasicAnimation animation]; 
frameAnimation.duration = 2.5; 
frameAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 

myLayer.actions = [NSDictionary dictionaryWithObjectsAndKeys:frameAnimation, @"frame", nil]; 

: 레이어에 대한 조치는 애니메이션과 애니메이션의 모든 프레임을 변경하려면메소드 참조를 통해 레이어가 해당 속성을 애니메이션으로 적용 할 액션을 찾는 방법을 찾을 수 있습니다.

+1

감사합니다. 블라디미르. CALayer가 프레임 속성을 직접 애니메이션으로 만들 수 없다는 것을 발견했습니다. 문서에 회색 상자가 있습니다. 어떤 이유로 그것을 보지 못했습니다. – dontWatchMyProfile

+6

마지막 줄은 그대로입니다. addAnimation에서 지정한 키는 임의의 NSString이 될 수 있습니다. 실제 답변은 베릴륨이 – Mattia

+0

이하라고 생각합니다 [myLayer addAnimation : frameAnimation forKey : @ "frame"]; "프레임"은 애니메이션의 이름 일 뿐이며 실제 속성과 아무런 관련이 없습니다. –

82

CALayer의 frame 속성은 위치, anchorPoint, bounds 및 transform에 따라 파생 속성입니다. 프레임에 애니메이션을 적용하는 대신 달성하려는 효과에 따라 위치 또는 경계를 애니메이션으로 처리해야합니다.

-(void)resizeLayer:(CALayer*)layer to:(CGSize)size 
{ 
    // Prepare the animation from the old size to the new size 
    CGRect oldBounds = layer.bounds; 
    CGRect newBounds = oldBounds; 
    newBounds.size = size; 
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"bounds"]; 

    // NSValue/+valueWithRect:(NSRect)rect is available on Mac OS X 
    // NSValue/+valueWithCGRect:(CGRect)rect is available on iOS 
    // comment/uncomment the corresponding lines depending on which platform you're targeting 

    // Mac OS X 
    animation.fromValue = [NSValue valueWithRect:NSRectFromCGRect(oldBounds)]; 
    animation.toValue = [NSValue valueWithRect:NSRectFromCGRect(newBounds)]; 
    // iOS 
    //animation.fromValue = [NSValue valueWithCGRect:oldBounds]; 
    //animation.toValue = [NSValue valueWithCGRect:newBounds]; 

    // Update the layer's bounds so the layer doesn't snap back when the animation completes. 
    layer.bounds = newBounds; 

    // Add the animation, overriding the implicit animation. 
    [layer addAnimation:animation forKey:@"bounds"]; 
} 

당신은 CAAnimationGroup 경우를 사용하여 이러한 애니메이션을 결합 할 수 있습니다 :

-(void)moveLayer:(CALayer*)layer to:(CGPoint)point 
{ 
    // Prepare the animation from the current position to the new position 
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"]; 
    animation.fromValue = [layer valueForKey:@"position"]; 

    // NSValue/+valueWithPoint:(NSPoint)point is available on Mac OS X 
    // NSValue/+valueWithCGPoint:(CGPoint)point is available on iOS 
    // comment/uncomment the corresponding lines depending on which platform you're targeting 

    // Mac OS X 
    animation.toValue = [NSValue valueWithPoint:NSPointFromCGPoint(point)]; 
    // iOS 
    //animation.toValue = [NSValue valueWithCGPoint:point]; 

    // Update the layer's position so that the layer doesn't snap back when the animation completes. 
    layer.position = point; 

    // Add the animation, overriding the implicit animation. 
    [layer addAnimation:animation forKey:@"position"]; 
} 

레이어의 크기를 조정하려면, 당신은 bounds 매개 변수를 애니메이션 것 :

레이어를 이동하려면 position (가) 애니메이션을 적용 할 수 있습니다 레이어를 동시에 이동하고 크기를 조정해야합니다.

+0

매우 도움이되는 링크를 제공해 주셔서 감사합니다. – RonLugge

+0

나는 받아 들여진 응답에 의해 떨어져 던졌다. 고맙습니다! –

+3

이것은 허용 된 대답이어야합니다. – CodeReaper

6

우리는 다음과 같은

-(void)handleTap2:(UITapGestureRecognizer *)recognizer { 

    UIImageView *vw = (UIImageView *)[recognizer view]; 

    CGPoint startPoint = CGPointMake(vw.frame.size.width/2+vw.frame.origin.x, vw.frame.size.height/2+vw.frame.origin.y); 
    CGPoint endPoint = CGPointMake(160, 240); 

    CGRect startBounds = vw.bounds; 
    CGRect stopBounds = self.view.bounds; 

    layer = [CALayer layer]; 
    layer.frame = self.view.frame; 
    layer.contents = (id)[vw.image CGImage]; 

    [self.view.window.layer addSublayer:layer]; 

    CABasicAnimation * baseAnimation = [CABasicAnimation animationWithKeyPath:@"position"]; 

    baseAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
    baseAnimation.fromValue = [NSValue valueWithCGPoint:startPoint] ; 
    baseAnimation.toValue = [NSValue valueWithCGPoint:endPoint] ; 

    CABasicAnimation * boundsAnimation = [CABasicAnimation animationWithKeyPath:@"bounds"]; 

    boundsAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
    boundsAnimation.fromValue = [NSValue valueWithCGRect:startBounds] ; boundsAnimation.toValue = [NSValue valueWithCGRect:stopBounds] ; 

    CAAnimationGroup * group =[CAAnimationGroup animation]; 
    group.removedOnCompletion=NO; group.fillMode=kCAFillModeForwards; 
    group.animations =[NSArray arrayWithObjects:baseAnimation, boundsAnimation, nil];  
    group.duration = 0.7; 

    [layer addAnimation:group forKey:@"frame"]; 
} 
3

문제는 골동품이다 "경계"과 애니메이션을하는 "위치"의 속성을 변경할 수 있습니다,하지만 난 어쨌든 그것을 응답 할 것이다.

프레임 속성을 애니메이션화 할 수 없습니다. 다른 속성을 애니메이션화해야합니다. 또한 암시 적 애니메이션을 비활성화해야합니다.

let updatedBounds = ... 
    let animation = CABasicAnimation(keyPath: "bounds") 
    animation.duration = 0.5 
    //it's better to start animation from presentation layer in case there is already animation going on 
    animation.fromValue = customLayer.presentation()?.bounds 
    animation.toValue = updatedBounds 
    customLayer.add(animation, forKey: nil) 

    //disable implicit animation for thoose properties 
    CATransaction.begin() 
    CATransaction.setDisableActions(true) 
    //update properties so they will be updated at the end of animation 
    customLayer.bounds = updatedBounds 
    customLayer.position = originalRect.origin 
    customLayer.anchorPoint = CGPoint(x: 0, y: 0) 
    CATransaction.commit() 
1

다음은 누군가를 도울 수있는 간단하고 완벽한 예제입니다.

클래스에 .slideUp()으로 전화하면 슬라이드됩니다.

class Slidey: YourViewClass { 

    func slideUp() { 

     print("\n\n SLIDE") 

     let FF = layer.position 
     var TT = FF 
     TT.y -= 100 
     print(FF) 
     print(TT) 

     CATransaction.begin() 
     CATransaction.setDisableActions(true) 

     CATransaction.setCompletionBlock{ [weak self] in 

      print("DONE") 
     } 

     let a = CABasicAnimation(keyPath: "position") 

     a.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut) 

     a.isCumulative = false 
     a.autoreverses = false 
     a.isRemovedOnCompletion = true 
     a.repeatCount = 0 
     a.fromValue = FF 
     a.toValue = TT 
     a.duration = 0.70 
     layer.add(a, forKey: nil) 

     CATransaction.commit() 
    } 
} 
관련 문제