2012-05-04 9 views
10
[CATransaction begin]; 
      [CATransaction setAnimationDuration:5]; 
      CGAffineTransform currentTransform = squareLayer.affineTransform; 
      CGFloat angle = M_PI; 

      squareLayer.affineTransform = CGAffineTransformRotate(currentTransform, angle); 
      [CATransaction commit]; 

Tại sao xoay vòng của tôi chỉ đi ngược chiều kim đồng hồ khi tôi muốn đi theo chiều kim đồng hồ?

[CATransaction begin]; 
      [CATransaction setAnimationDuration:5]; 
      CGAffineTransform currentTransform = squareLayer.affineTransform; 
      CGFloat angle = (M_PI * -1); 

      squareLayer.affineTransform = CGAffineTransformRotate(currentTransform, angle); 
      [CATransaction commit]; 

Tôi đã có thể nghĩ -1 sẽ đảo ngược hướng nhưng dường như không?

Trả lời

12

Góc là như nhau. Để đi vòng tròn đầy đủ, bạn cần 2 * Pi, vì vậy nửa vòng tròn là Pi. Nếu bạn lấy -Pi nó sẽ kết thúc tại cùng một điểm.

CHỈNH SỬA: Nếu bạn cần xoay nó theo chiều kim đồng hồ, bạn có thể hơi tắt đi -Pi. Thay vì -M_PI sử dụng -3.141593 ví dụ.

+0

Tôi đồng ý Nhưng tôi cần xoay 180 độ theo chiều kim đồng hồ. Whats cách tốt nhất để hoạt động này là gì? Chúc mừng – geminiCoder

+1

Vâng, nó sẽ xoay theo hướng ngắn nhất.Nếu độ chính xác không phải là vấn đề lớn, bạn có thể xoay nhẹ xuống dưới hoặc trên 180 độ. Đó là một sửa chữa nhanh chóng và bẩn nhưng có lẽ sẽ làm việc. – RadicalRaid

+0

Chỉ cần xem bản chỉnh sửa của bạn. Nó hoạt động tốt nhưng dường như không hoàn hảo chút nào. – geminiCoder

2

Dưới đây là trích dẫn từ tài liệu về apple "Trong iOS, giá trị dương xác định xoay vòng ngược và giá trị âm xác định xoay theo chiều kim đồng hồ." Bạn đã thử làm điều này chưa:

squareLayer.affineTransform = CGAffineTransformRotate(currentTransform, -M_PI); 

Đó là những gì tôi đã sử dụng để thực hiện tất cả xoay theo chiều kim đồng hồ trong quá khứ.

+0

Vâng, đây là vấn đề. Như bạn thấy trong mã của tôi ở trên, điều này không hoạt động. Không biết tại sao? – geminiCoder

3

Trải nghiệm của tôi với Core animatinon không đồng ý với trích dẫn của Apple. Những gì tôi đã tìm thấy là điều duy nhất quan trọng là giá trị góc cuối cùng. Tích cực pi và pi tiêu cực quay kết quả trong cùng một ma trận chuyển đổi, do đó, hệ thống chỉ đi counter-clockwize bất kể.

Những gì tôi đã thực hiện để quay theo một hướng cụ thể hoặc xoay 360 độ đầy đủ, là tạo CABasicAnimation rõ ràng bằng cách sử dụng loại như transform.rotation.z, với chế độ điền được đặt thành kCAFillModeForwards và chỉ cung cấp một toValue. Điều đó làm cho hoạt ảnh bắt đầu từ giá trị trước đó. Sau đó, bạn có thể thiết lập xoay vòng thậm chí là một phần nhỏ trong tổng số vòng quay mong muốn của bạn và cho nó một số lần lặp lại.

Ví dụ: mã bên dưới tạo hoạt ảnh xoay vòng 5 phần tư hoặc 450 độ. Nếu bạn muốn làm 180 độ chiều kim đồng hồ, bạn có thể vòng xoay cảng gồm pi/2 với một số lặp lại 2. Đối ngược, sử dụng -pi/2 với một số lặp lại 2.

CABasicAnimation* rotate = [CABasicAnimation animationWithKeyPath: 
    @"transform.rotation.z"]; 
    rotate.removedOnCompletion = FALSE; 
    rotate.fillMode = kCAFillModeForwards; 

    //Do a series of 5 quarter turns for a total of a 1.25 turns 
    //(2PI is a full turn, so pi/2 is a quarter turn) 
    [rotate setToValue: [NSNumber numberWithFloat: -M_PI/2]]; 
    rotate.repeatCount = 5; 

    rotate.duration = duration/rotate.repeatCount * 2 ; 
    rotate.beginTime = start; 
    rotate.cumulative = TRUE; 
    rotate.timingFunction = [CAMediaTimingFunction 
    functionWithName:kCAMediaTimingFunctionLinear]; 
7

Chỉ cần chạy vào này và trong khi giải pháp của @ radicalraid hoạt động tốt, tôi thích điều chỉnh góc bắt đầu trước khi xoay vs quay sang một góc nhỏ hơn điểm kết thúc mong muốn. Ngoài ra, bạn có thể animate CALayer biến đổi bằng cách sử dụng các khối hoạt hình.

Mã của tôi:

// iOS will rotate the shortest distance to the end angle, 
// using counter-clockwise if equal. 
// Force the rotation to open clockwise and close counter-clockwise by bumping 
// the initial angle 
CGFloat startRadians, endRadians; 
if (isOpening) { 
    startRadians = 0.01f; 
    endRadians = M_PI; 

} 
else { 
    startRadians = M_PI - 0.01f; 
    endRadians = 0.0f; 
} 

self.myImageView.layer.affineTransform = CGAffineTransformMakeRotation(startRadians); 

[UIView animateWithDuration:0.3f 
       animations:^{ 
        self.myImageView.layer.affineTransform = CGAffineTransformMakeRotation(endRadians); 
       }]; 
0

Đồng ý với Duncan và XJones. Giá trị cuối cùng là tất cả những gì có vẻ quan trọng. CA sau đó sẽ tìm đường đi ngắn nhất.

Sử dụng ý tưởng của XJones. Điều này dường như làm việc cho tôi:

private let angleRadians = CGFloat(M_PI) 
private let angleRadiansOffset = CGFloat(0.1 * M_PI/180.0) 

let turnAngle = angleRadians - angleRadiansOffset; 

//pre-rotate by an 'invisible amount', to force rotation in the same direction every time 
primView.layer.transform = CATransform3DRotate(primView.layer.transform, angleRadiansOffset, 0.0, 1.0, 0.0) 

UIView.animateKeyframesWithDuration(duration, delay: 0, options: [.BeginFromCurrentState], animations: {() -> Void in 

    UIView.addKeyframeWithRelativeStartTime(0, relativeDuration: 0.8, animations: {() -> Void in 

     //now we will complete the rotation to the correct end value 
     primView.layer.transform = CATransform3DRotate(primView.layer.transform, turnAngle, 0.0, 1.0, 0.0) 

    }) 

    //... other code .... 

}) { (finished) -> Void in 

} 
1

EDIT: Thay vì sử dụng -M_PI -3 * M_PI, cho chống chiều kim đồng hồ

và loại bỏ '-' dấu hiệu cho hướng ngược lại.