2009-02-18 20 views
8

Tôi có một số CALayers mà tôi đang cố gắng tạo hiệu ứng cho một zPosition mới với mỗi lớp hơi bị trễ một chút.hoạt hình nhiều CALayer, nhưng không phải trong cùng một khoảng thời gian

Mỗi hoạt ảnh sẽ mất 0,25 giây và bắt đầu 0,05 giây sau khi hoạt ảnh trước đó bắt đầu. Vào cuối mỗi hoạt hình, lớp sẽ được gỡ bỏ khỏi cây lớp.

Tôi đã sử dụng phương pháp đại biểu -animationDidStop:finished: ủy quyền để xóa lớp của mình khi chúng kết thúc nhưng tôi không thể đặt hàng hoạt ảnh chính xác.

Có thể lập lịch hoạt ảnh theo cách này hay không và làm cách nào?

Trả lời

17

Tôi vẫn muốn nghe đề xuất của người khác nhưng tôi nghĩ tôi đã giải quyết vấn đề này.

Tôi hiện đang tạo các đối tượng cụ thể CAAnimation và chỉ định thuộc tính beginTime của mình. Tôi đã làm điều này trước đó và nó đã không được làm việc, những gì tôi cuối cùng nhận ra là cho các tài sản beginTime để được vinh danh các hình ảnh động đã được thêm vào một CAAnimationGroup.

Vì vậy, mã của tôi trông như thế này:

NSArray *layers = /* layers to be animated away */ 
CGFloat startOffset = 0.01; 

for (NSInteger index = 0; index < layers.count; index++) { 
    CALayer *layer = [layers objectAtIndex:index]; 

    CABasicAnimation *zoomOut = [CABasicAnimation animationWithKeyPath:@"zPosition"]; 
    zoomOut.toValue = [NSNumber numberWithDouble:400.0]; 
    zoomOut.beginTime = index * startOffset; 

    CAAnimationGroup *group = [CAAnimationGroup animation]; 
    group.animations = [NSArray arrayWithObject:zoomOut]; 
    group.delegate = self; 

    [layer addAnimation:group forKey:@"zoomAway"]; 
} 
+0

Tôi cũng đang tìm kiếm câu trả lời cao và thấp, và thử nhiều thứ khác nhau. Tôi nghĩ rằng nó sẽ có thể tạo ra một CAAnimationGroup chia sẻ mà tất cả các lớp có thể chia sẻ như là một khung thời gian tham chiếu, nhưng điều đó rõ ràng không hoạt động. Bây giờ tôi nghĩ rằng đây có lẽ là cách để đi về nó, nhưng cũng rất thích nghe từ những người khác với cái nhìn sâu sắc hơn về điều này. – Felixyz

0

Cảm ơn để chia sẻ kết quả của bạn, tôi cũng phát hiện ra rằng tài sản BeginTime không hoạt động nếu sử dụng mà không một nhóm.

Trong trường hợp của tôi, một số cài đặt như BeginTime và Duration bị bỏ qua nếu được đặt trên CABasicAnimation, nhưng đã hoạt động nếu đặt trực tiếp CAAnimationGroup.

14

Tôi đã tìm thấy thuộc tính BeginTime thực sự hoạt động mà không đưa hoạt ảnh vào nhóm nếu bạn căn cứ giá trị của nó dưới dạng delta từ giá trị được trả về bởi hàm CACurrentMediaTime() của QuartzCore.

ví dụ: anim.beginTime = CACurrentMediaTime() + 0.05;

+0

tuyệt. Tôi không nhớ đã cố gắng khi tôi làm điều này ban đầu. –

5

Tôi ước gì có đại diện để bình luận, nhưng lý do rằng việc thiết anim.beginTime để CACurrentMediaTime() công trình được tiết lộ bởi một số tài liệu khác:

AVCoreAnimationBeginTimeAtZero Sử dụng liên tục này để thiết lập tài sản beginTime hoạt hình của CoreAnimation là thời gian 0. Hằng số là một giá trị nhỏ, khác 0, ngăn cản CoreAnimation thay thế 0.0 bằng CACurrentMediaTime. Có sẵn trong iOS 4.0 trở lên. Được khai báo trong AVAnimation.h.

Vì vậy, thiết lập bình thường của beginTime thành 0 là viết tắt để đặt nó thành CACurrentMediaTime(). Vì vậy, bạn có thể sử dụng để tách rời sự khởi đầu của các nhóm khác nhau.

+0

"Vì vậy, các thiết lập bình thường của beginTime đến 0 là viết tắt để thiết lập nó để CACurrentMediaTime()", wow, đã được tìm kiếm trên tất cả cho lời giải thích này, cảm ơn rất nhiều. – langtutheky

0

Swift 3

Hóa ra bạn có thể làm điều này tương đối đơn giản bằng cách làm như sau:

var timeOffset:Double = 0 
let delay:Double = 0.1 
for layer in layers { 
    let a = CABasicAnimation(keyPath: "path" 
    a.fromValue = layer.ovalPathSmall.cgPath 
    a.toValue = layer.ovalPathLarge.cgPath 
    a.fillMode = kCAFillModeForwards 
    a.beginTime = CACurrentMediaTime() + timeOffset 
    a.duration = 0.3 
    a.isRemovedOnCompletion = true 
    layer.add(a, forKey: nil) 

    timeOffset += 0.3 + delay 
} 

Tất cả các lớp được CALayer hoặc CAShapeLayer, và trong trường hợp bạn đang tự hỏi điều gì ovalPathSmall và ovalPathLarge là:

ovalPathSmall = UIBezierPath(arcCenter: position, radius: smallRadius, startAngle: 0, endAngle: 2 * .pi, clockwise: true) 
ovalPathLarge = UIBezierPath(arcCenter: position, radius: largeRadius, startAngle: 0, endAngle: 2 * .pi, clockwise: true) 
Các vấn đề liên quan