2009-10-11 21 views
44

Tôi đang làm điều này để tìm hiểu cách làm việc với các tính năng hoạt hình chính trên iPhone (không phải tìm hiểu cách ghép hình ảnh, mỗi lần sử dụng).Làm thế nào để chuyển giữa 2 hình ảnh trên iPhone bằng cách sử dụng Core Animation

Đọc câu hỏi tương tự trên SO dẫn tôi để tin rằng nó có thể được thực hiện bằng hoạt cảnh .contents tài sản của UIImageView củalớp như vậy:

UIImage *image1 = [UIImage imageNamed:@"someImage1.png"]; 
UIImage *image2 = [UIImage imageNamed:@"someImage2.png"]; 

self.imageView.image = image1; 
[self.view addSubview:self.imageView]; 

CABasicAnimation *crossFade = [CABasicAnimation animationWithKeyPath:@"contents"]; 
crossFade.duration = 5.0; 
self.imageView.layer.contents = image2; 
[self.imageView.layer addAnimation:crossFade forKey:@"animateContents"]; 

đã tôi nhận được một chi tiết sai hoặc điều này là không thể.

Cập nhật: mã ở trên tạo ra UIImageView trống. Khi tôi thay đổi dòng này:

self.imageView.layer.contents = image2.CGImage; 

... Tôi có thể nhìn thấy hình ảnh ngay bây giờ nhưng không phai mờ, nó sẽ xuất hiện ngay lập tức.

Trả lời

78

Bạn sắp hoàn tất.

CABasicAnimation *crossFade = [CABasicAnimation animationWithKeyPath:@"contents"]; 
crossFade.duration = 5.0; 
crossFade.fromValue = image1.CGImage; 
crossFade.toValue = image2.CGImage; 
[self.imageView.layer addAnimation:crossFade forKey:@"animateContents"]; 

Lưu ý rằng hoạt ảnh độc lập với giá trị/nội dung thực tế của UIImageView. Do đó, bạn cần phải

self.imageView.image = image2; 

... để đặt kết quả cuối cùng cho hình ảnh của bạn.

+0

Nó hoạt động, crossfading hình ảnh.Làm thế nào để bạn ngăn chặn các cảnh báo trình biên dịch "Đi qua đối số 1 của 'setFromValue:' từ loại con trỏ không tương thích" – willc2

+2

.fromValue và .toValue mong đợi một con trỏ đến một đối tượng Objective-C, không phải là một con trỏ đến một CFType như CGImageRef là. Do đó, bạn có thể làm điều này: crossFade.fromValue = (id) (image1.CGImage); crossFade.toValue = (id) (image2.CGImage); –

+0

Có thể có điều gì đó tương tự được thực hiện cho màu văn bản/màu nền, trên UIButton chẳng hạn? – ebi

0

Đề xuất của tôi sẽ chỉ sử dụng hai số UIImageView s trên đầu trang của nhau. Cái ở trên cùng có hình ảnh1 và phía dưới là hình ảnh2:

- (void) crossfade { 
    [UIView beginAnimations:nil context:nil]; 
    [UIView setAnimationDuration:.5]; 
    imageView1.alpha = !imageView1.alpha; 
    [UIView commitAnimations]; 
} 

Điều đó sẽ mờ dần giữa hai hình ảnh bất cứ khi nào bạn gọi. Nếu bạn muốn chỉ cần làm một phai duy nhất và loại bỏ các hình ảnh đầu tiên sau khi bạn đã hoàn tất:

- (void) crossfade { 
    [UIView beginAnimations:nil context:nil]; 
    [UIView setAnimationDuration:.5]; 
    [UIView setAnimationDelegate:imageView1]; 
    [UIView setAnimationDidStopSelector:@selector(removeFromSuperview)]; 
    imageView1.alpha = 0 
    [UIView commitAnimations]; 
} 

Edit:

Nếu bạn đang tìm kiếm một lý do tại sao mã của bạn không hoạt động , đó là vì bạn chỉ cần đặt thuộc tính cho hình ảnh mới, sau đó thêm hoạt ảnh vô dụng. CABasicAnimationfromValuetoValue cần được đặt, sau đó thêm hoạt ảnh đó vào lớp và sẽ làm hoạt ảnh. Không đặt nội dung theo cách thủ công.

+0

Bạn trả lời đang được đánh giá cao nhưng tôi đang cố gắng để tìm hiểu về tính chất animatable CA và cú pháp của việc sử dụng chìa khóa đường dẫn chứ không phải là làm thế nào để vượt qua hình ảnh phai cho mỗi se. Bạn có biết những gì tôi đang làm sai trong mẫu mã của tôi? – willc2

60

Tôi thấy điều này ở đâu đó - nó hoạt động tuyệt vời.

UIImage * toImage = [UIImage imageNamed:@"image.png"]; 
[UIView transitionWithView:self.view 
        duration:0.33f 
        options:UIViewAnimationOptionTransitionCrossDissolve 
       animations:^{ 
        self.imageview.image = toImage; 
       } completion:NULL]; 
+0

Đã làm việc trong trường hợp các giải pháp đề xuất khác không thành công. –

+0

Thẳng thắn và đơn giản, không có cảm ơn, v.v. –

+0

Giải pháp Rocking! – phatmann

19
extension UIImageView 
{ 
    func mySetImage(image:UIImage) 
    { 
     guard let currentImage = self.image where currentImage != image else { return } 
     let animation = CATransition() 
     animation.duration = 0.3 
     animation.type = kCATransitionFade 
     layer.addAnimation(animation, forKey: "ImageFade") 
     self.image = image 
    } 
} 
+0

siêu đơn giản và siêu hiệu quả! cảm ơn. IMO cách tiếp cận tốt nhất là mở rộng UIImageView và ghi đè setImage bằng đường này – talkol

+0

Đồng ý. Đây là một giải pháp đơn giản hơn nhiều. –

+3

Việc so sánh hai hình ảnh có khả năng rất tốn kém, tôi không khuyên bạn nên chuyển đổi hai hình ảnh sang PNG chỉ để so sánh nếu chúng giống nhau. – steipete

1
- (void)viewDidLoad 
{ 
[super viewDidLoad]; 
// Do any additional setup after loading the view from its nib. 
self.navigationController.navigationBarHidden=false; 
UIImage *img=[UIImage imageNamed:@"images.jpeg"]; 
imgview=[[UIImageView alloc]init]; 
imgview.frame=CGRectMake(30,90, img.size.width, img.size.height); 
[self.view addSubview:imgview]; 
[self animateImages]; 
} 
- (void)animateImages 
{ 
static int count = 0; 
NSArray *animationImages = @[[UIImage imageNamed:@"images.jpeg"], [UIImage imageNamed:@"images (1).jpeg"]]; 
UIImage *image = [animationImages objectAtIndex:(count % [animationImages count])]; 

[UIView transitionWithView:imgview 
        duration:2.0f // animation duration 
        options:UIViewAnimationOptionTransitionCrossDissolve 
       animations:^{ 
        imgview.image = image; 
       } completion:^(BOOL finished) { 
        [self animateImages]; 
        count++; 
       }]; 

}

+0

Mã đẹp cho bộ xoay hình ảnh mờ dần. Hoạt động tốt cho tôi. – Richard

1

Giải pháp trong nhanh chóng

let image1:UIImage = UIImage(named: "someImage1")!; 
let image2:UIImage = UIImage(named: "someImage2")!; 
let crossFade:CABasicAnimation = CABasicAnimation(keyPath: "contents"); 
crossFade.duration = 5.0; 
crossFade.fromValue = image1.CGImage; 
crossFade.toValue = image2.CGImage; 
imageView.layer.addAnimation(crossFade, forKey:"animateContents"); 
Các vấn đề liên quan