2012-03-02 28 views
13

Tôi đã sử dụng CAKeyframeAnimations để tạo hoạt ảnh cho các thuộc tính transform.rotationtransform.translation.x của lớp, nhưng tôi đang gặp sự cố khi kích hoạt thuộc tính transform một cách hoàn toàn. Tôi có một lớp mà phải animate giữa hai tiểu bang và nội suy mặc định của CABasicAnimation là hoàn toàn không chính xác và không theo con đường tôi muốn. CAKeyframeHình ảnh để giải cứu, hoặc vì vậy tôi nghĩ. Bất kỳ nỗ lực nào để tạo hiệu ứng động transform bằng cách sử dụng CAKeyframeKết quả tạo kết quả trong chế độ xem ngay lập tức chụp với biến đổi cuối cùng trong khi các hoạt ảnh khác chạy. Nếu tôi loại bỏ nửa đầu của hàm sau và để các sự kiện "biến đổi" của tôi sử dụng CABasicAnimation ở phía dưới, nó sẽ hoạt hình tốt - mặc dù với các biến đổi nội suy không chính xác trên đường đi.Làm cách nào để tạo hoạt ảnh cho CATransform3Ds bằng CAKeyframeAnimation?

lớp đại biểu của tôi đã thực hiện như sau:

- (id <CAAction>) actionForLayer:(CALayer *)layer forKey:(NSString *)event 
{  
    if ([event isEqualToString:@"transform"]) 
    { 
     CGSize startSize = ((CALayer *)self.layer.presentationLayer).bounds.size; 
     CGSize endSize = self.layer.bounds.size; 

     CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:event]; 
     animation.duration = 0.25; 

     NSMutableArray *values = [NSMutableArray array]; 

     int stepCount = 10; 
     for (int i = 0; i < stepCount; i++) 
     { 
      CGFloat p = i/(float)(stepCount - 1); 
      CGSize size = [self interpolateBetweenSize:startSize andSize:endSize percentage:p]; 
      CATransform3D transform = [self transformForSize:size]; 
      [values addObject:[NSValue valueWithCATransform3D:transform]]; 
     } 

     animation.values = values; 
     return animation; 
    } 

    // All other animations use this basic animation 
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:event]; 
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
    animation.removedOnCompletion = YES; 
    animation.fillMode = kCAFillModeForwards; 
    animation.duration = 0.25; 
    return animation; 
} 

tôi chuyển đổi là bản dịch tiếp theo là một xoay, nhưng tôi nghĩ rằng một phim hoạt hình nhóm với hình ảnh động keyframe riêng biệt sinh động thông qua một dịch VÀ một xoay sẽ cho kết quả điên thị trấn. Tôi đã xác nhận rằng kích thước & biến đổi là chính xác cho tất cả các giá trị của p mà tôi vượt qua mặc dù và p đúng phạm vi từ 0 đến 1.

Tôi đã thử đặt chức năng thời gian không mặc định, tôi đã thử cài đặt một loạt các hàm thời gian, tôi đã bỏ qua keyTImes, tôi đã thiết lập một repeatCount là 0, removeOnCompletion = YES, và một fillMode của tiền đạo và điều đó không có hiệu lực. Tôi không tạo hoạt ảnh keyframe biến đổi chính xác phải không?

+1

Bạn có thể làm rõ hiệu ứng chính xác mà bạn đang cố gắng đạt được không? Bạn mô tả nó như là một bản dịch theo sau bởi một vòng quay, nhưng từ mã của bạn có vẻ như các giới hạn cũng đang hoạt hình - điều đó có đúng không?Bạn muốn các lớp để di chuyển, sau đó xoay, với các bounds phát triển hoặc thu hẹp liên tục trong suốt cả hai giai đoạn của di chuyển/xoay hình ảnh động? – GSnyder

+0

Tại sao cần phải ngầm định? Mã này trông rất khó hiểu. Nếu bạn muốn kiểm soát hạt mịn tại sao không chỉ tạo ra các hình ảnh động và thêm nó trực tiếp vào lớp, mà bạn nói rằng bạn đã làm việc chưa? Cũng chỉ cần trả về 'nil' từ phương thức ủy nhiệm đó nếu bạn muốn mọi thứ sử dụng hoạt ảnh mặc định của họ. –

Trả lời

0

Kỹ thuật này hoạt động trở lại trong iOS 3 nhưng dường như bị hỏng trong iOS 5.0.

5.1 'kỳ diệu' đã sửa lỗi này, có vẻ như đó là lỗi trong iOS 5.0. Tôi sẽ gửi một radar, nhưng nó hiện đang làm việc trong 5.1.

@Gsnyder: Một số nền: Tôi đang thử nghiệm với giao diện người dùng rõ ràng (đối với một cái gì đó hoàn toàn không liên quan đến Clear) và đã đưa ra điều này: http://blog.massivehealth.com/post/18563684407/clear. Điều đó sẽ giải thích sự cần thiết cho việc dịch & xoay.

Tôi đã tạo một chuyển đổi màn trập phân chia chế độ xem thành các lớp N (thay vì chỉ 2) trông giống như thế này khi được xem từ bên cạnh: /////.

Mã của tôi không hoạt ảnh giới hạn, nó đang sử dụng kích thước ở mỗi bước để xác định biến đổi cần thiết.

@ Paul.s: Ngụ ý cho phép tôi giữ sự trừu tượng này trong chính lớp lớp mà không làm ô nhiễm bộ điều khiển chế độ xem sở hữu nó. Bộ điều khiển xem chỉ nên thay đổi giới hạn xung quanh và lớp nên di chuyển một cách thích hợp. Tôi không phải là người hâm mộ bộ điều khiển xem có hàng tá hoạt ảnh tùy chỉnh khi chính chế độ xem có thể xử lý nó.

Tôi cần sử dụng hoạt ảnh khung hình chính vì hoạt ảnh mặc định giữa lớp chuyển đổi/và _ hoạt ảnh qua các góc không chính xác để /// \ lớp không xếp hàng trong suốt quá trình chuyển đổi. Các hoạt ảnh khung hình chính đảm bảo các cạnh tất cả đều được sắp xếp chính xác trong khi tất cả đều hoạt ảnh.

Tôi đang xem xét việc đóng này, điều này có vẻ là một lỗi trong iOS 5.0 và kể từ đó đã được sửa. Cảm ơn mọi người.

0
(void)animateViewWith3DCurrentView:(UIView *)currentView withPoing:(CGPoint)movePoint 
{ 
    //flip the view by 180 degrees in its place first. 
    currentView.layer.transform =   CATransform3DRotate(currentView.layer.transform,myRotationAngle(180), 0, 1, 0); 

    //set the anchor point so that the view rotates on one of its sides. 
    currentView.layer.anchorPoint = CGPointMake(0.5, 0.5); 

    //Set up scaling 

    CABasicAnimation *resizeAnimation = [CABasicAnimation animationWithKeyPath:kResizeKey]; 

    //we are going to fill the screen here. So 423,337 
    [resizeAnimation setToValue:[NSValue valueWithCGSize:CGSizeMake(423, 337)]]; 
    resizeAnimation.fillMode   = kCAFillModeForwards; 
    resizeAnimation.removedOnCompletion = NO; 

    // Set up path movement 

    UIBezierPath *movePath = [UIBezierPath bezierPath]; 

    //the control point is now set to centre of the filled screen. Change this to make the path different. 
    // CGPoint ctlPoint  = CGPointMake(0.0, 0.5); 
    CGPoint ctlPoint  = CGPointMake(1024/2, 768/2); 

    //This is the starting point of the animation. This should ideally be a function of the frame of the view to be animated. Hardcoded here. 

    // Set here to get the accurate point.. 
    [movePath moveToPoint:movePoint]; 

    //The anchor point is going to end up here at the end of the animation. 
    [movePath addQuadCurveToPoint:CGPointMake(1024/2, 768/2) controlPoint:ctlPoint]; 

    CAKeyframeAnimation *moveAnim = [CAKeyframeAnimation animationWithKeyPath:kPathMovement]; 

    moveAnim.path    = movePath.CGPath; 
    moveAnim.removedOnCompletion = YES; 

    // Setup rotation animation 

    CABasicAnimation* rotateAnimation = [CABasicAnimation animationWithKeyPath:kRotation]; 
    //start from 180 degrees (done in 1st line) 
    CATransform3D fromTransform  = CATransform3DMakeRotation(myRotationAngle(180), 0, 1, 0); 
    //come back to 0 degrees 
    CATransform3D toTransform   = CATransform3DMakeRotation(myRotationAngle(0), 0, 1, 0); 

    //This is done to get some perspective. 
    CATransform3D persp1 = CATransform3DIdentity; 
    persp1.m34 = 1.0/-3000; 

    fromTransform = CATransform3DConcat(fromTransform, persp1); 
    toTransform = CATransform3DConcat(toTransform,persp1); 

    rotateAnimation.toValue    = [NSValue valueWithCATransform3D:toTransform]; 
    rotateAnimation.fromValue   = [NSValue valueWithCATransform3D:fromTransform]; 
    //rotateAnimation.duration   = 2; 
    rotateAnimation.fillMode   = kCAFillModeForwards; 
    rotateAnimation.removedOnCompletion = NO; 


    // Setup and add all animations to the group 

    CAAnimationGroup *group = [CAAnimationGroup animation]; 

    [group setAnimations:[NSArray arrayWithObjects:moveAnim,rotateAnimation, resizeAnimation, nil]]; 

    group.fillMode   = kCAFillModeForwards; 
    group.removedOnCompletion = NO; 
    group.duration   = 0.7f; 
    group.delegate   = self; 

    [group setValue:currentView forKey:kGroupAnimation]; 

    [currentView.layer addAnimation:group forKey:kLayerAnimation]; 
} 
Các vấn đề liên quan