2012-12-19 45 views
5

// tập tin tiêu đề cho các lớp thẻRắc rối với CAAnimation

#import "OWCardView.h" 

@implementation OWCardView; 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     self.layer.contents  = (id) [UIImage imageNamed:@"4.png"].CGImage; 
     self.layer.shadowColor = [UIColor whiteColor].CGColor; 
     self.layer.shadowOpacity = 0.3; 
    } 
    return self; 
} 


- (void) moveCard:(float)xPoint along:(float)yPoint 
{ 
    CGRect someRect = CGRectMake(xPoint, yPoint, 72, 96); 

    [UIView animateWithDuration: 3.5 
          delay: 0.3 
         options: UIViewAnimationCurveEaseOut 
        animations: ^{ self.frame = someRect;} 
        completion: ^(BOOL finished) { }]; 
} 


@end 


// part of the Implementation in the view controller's viewDidLoad 

[...] 
    CGRect myImageRect = CGRectMake(20.0f, 20.0f, 72.0f, 96.0f); 

    // myCard is a property of the viewController 
    self.myCard = [[OWCardView alloc] initWithFrame:myImageRect]; 
    [self.view addSubview:self.myCard]; 
    [self.myCard moveCard: 240 along: 355];  // First call 
    [self.myCard moveCard: 50 along: 355];  // Second call 
    [self.myCard moveCard: 50 along: 50];  // Third call 
[...] 

Vấn đề: Chỉ có tin nhắn cuối cùng để moveCard trong viewController được thực hiện; các cuộc gọi đầu tiên và thứ hai không thực thi. Có gì sai với mã?

Khi tôi nhận xét thư thứ ba di chuyển thẻ ra, cuộc gọi thứ hai được thực hiện và lệnh đầu tiên không được thực hiện. Nếu tôi nhận xét cuộc gọi thứ hai và thứ ba, thì cuộc gọi đầu tiên sẽ thực hiện. Nhưng tôi muốn tất cả ba hình ảnh động xuất hiện trên thẻ.

Trả lời

1

Sự cố mà bạn có là hoạt ảnh không đồng bộ.

Mã không chờ cho mỗi hoạt ảnh kết thúc trước khi thực hiện bước tiếp theo. Vì vậy, nó thổi qua hai cuộc gọi đầu tiên và bắt đầu hoạt hình thứ ba ngay lập tức và hủy bỏ hai ý nghĩa đầu tiên mà bạn sẽ chỉ nhìn thấy hình ảnh động cuối cùng.

Bạn phải sử dụng khối đã hoàn thành để thực hiện điều gì đó sau khi hoạt ảnh kết thúc.

Cách đơn giản để làm điều này là như vậy ...

[UIView animateWithDuration: 3.5 
         delay: 0.3 
        options: UIViewAnimationCurveEaseOut 
       animations: ^{ self.frame = CGRectMake(240, 355, 72, 96);} 
       completion: ^(BOOL finished) { 
    [UIView animateWithDuration: 3.5 
          delay: 0.3 
         options: UIViewAnimationCurveEaseOut 
        animations: ^{ self.frame = CGRectMake(50, 355, 72, 96);} 
        completion: ^(BOOL finished) { 
     [UIView animateWithDuration: 3.5 
           delay: 0.3 
          options: UIViewAnimationCurveEaseOut 
         animations: ^{ self.frame = CGRectMake(50, 50, 72, 96);} 
         completion: ^(BOOL finished) { 
      //All finished 
     }]; 
    }]; 
}]; 

Bạn có thể đặt điều này vào một số loại hàm đệ quy nhưng đây có thể dễ dàng hơn để làm điều này.

Cách khác là sử dụng hoạt ảnh khung hình chính nơi bạn xây dựng đường dẫn và thời gian theo từng bước và sau đó nói "GO" và nó sẽ làm hoạt ảnh bạn đã tạo.

Điều này có lẽ dễ dàng hơn bây giờ và tôi đã sử dụng loại điều này trước đây.

+0

Nhờ đó là hữu ích – Stoner

1

các hoạt hình thứ ba ghi đè fisrt và lần thứ hai một

bạn có thể sử dụng

- (void) moveCard:(CGPoint)Point1 point2:(CGPoint)Point2 point3:(CGPoint)Point3 
{ 
    CGRect someRect = CGRectMake(Point2.x, Point2.y, 72, 96); 

    [UIView animateWithDuration: 3.5 
          delay: 0.3 
         options: UIViewAnimationCurveEaseOut 
        animations: ^{ self.frame = someRect;} 
        completion: ^(BOOL finished) { 
         someRect = CGRectMake(Point2.x, Point2.y, 72, 96); 
         [UIView animateWithDuration: 3.5 
               delay: 0.3 
              options: UIViewAnimationCurveEaseOut 
              animations: ^{ self.frame = someRect;} 
              completion: ^(BOOL finished) { 

               someRect = CGRectMake(Point3.x, Point3.y, 72, 96); 
               [UIView animateWithDuration: 3.5 
                    delay: 0.3 
                    options: UIViewAnimationCurveEaseOut 
                   animations: ^{ self.frame = someRect;} 
                   completion: ^(BOOL finished) { 



                   }]; 

              }]; 

        }]; 
} 
+0

này sẽ không làm việc. Các điểm bạn đang sử dụng không chính xác. Bên cạnh đó, nếu hoạt hình luôn giống nhau (có vẻ như nó là) thì bạn đang quá tải toàn bộ quá trình. – Fogmeister

+0

có thể bạn có quyền, phương pháp này quá phức tạp quá trình, nhưng tôi làm việc trong trường hợp này. bất kỳ cách nào thx cho commet có giá trị của bạn –

+0

Cảm ơn đó là hữu ích – Stoner

2

Khi bạn động một cái nhìn, bất kỳ hình ảnh động trước bạn áp dụng cho các điểm bị hủy ngay lập tức , ngay cả khi một trong hai hình động có độ trễ khác 0. Vì vậy, nếu bạn muốn áp dụng các hoạt ảnh tuần tự, bạn phải thêm hoạt ảnh thứ hai sau khi hoạt ảnh đầu tiên kết thúc. Bạn có thể sử dụng khối hoàn thành để phát hiện khi hoạt ảnh đầu tiên kết thúc.

Nó khá dễ dàng để làm moveCard:along: duy trì một danh sách các hình chữ nhật mục tiêu và áp dụng các hình ảnh động tuần tự:

@implementation OWCardView { 
    NSMutableArray *pendingRects; 
    BOOL isAnimating; 
} 

- (void)moveCard:(float)xPoint along:(float)yPoint { 
    CGRect someRect = CGRectMake(xPoint, yPoint, 72, 96); 
    if (!pendingRects) { 
     pendingRects = [NSMutableArray array]; 
    } 
    [pendingRects addObject:[NSValue valueWithCGRect:someRect]]; 
    [self startAnimatingIfNeeded]; 
} 

- (void)startAnimatingIfNeeded { 
    if (isAnimating) 
     return; 
    if (pendingRects.count == 0) 
     return; 
    CGRect rect = [[pendingRects objectAtIndex:0] CGRectValue]; 
    [pendingRects removeObjectAtIndex:0]; 

    isAnimating = YES; 
    [UIView animateWithDuration:3.5 delay:0.3 options:UIViewAnimationCurveEaseOut animations:^{ 
     self.frame = rect; 
    } completion:^(BOOL finished) { 
     isAnimating = NO; 
     [self startAnimatingIfNeeded]; 
    }]; 
} 
+0

Cảm ơn đó là hữu ích – Stoner

Các vấn đề liên quan