Làm cách nào để tạo hiệu ứng thay đổi hình ảnh trong UIImageView?


199

Tôi có UIImageViewmột hình ảnh. Bây giờ tôi có một hình ảnh hoàn toàn mới (tệp đồ họa) và muốn hiển thị nó trong này UIImageView. Nếu tôi chỉ thiết lập

myImageView.image = newImage;

hình ảnh mới được nhìn thấy ngay lập tức. Không hoạt hình.

Tôi muốn nó mờ dần vào hình ảnh mới. Tôi nghĩ có lẽ có một giải pháp tốt hơn là chỉ tạo ra một cái mới UIImageViewtrên đó và pha trộn với hoạt hình?


Câu trả lời:


260

Tôi không chắc liệu bạn có thể làm động các UIView với hiệu ứng mờ dần không vì dường như tất cả các chuyển đổi chế độ xem được hỗ trợ đều được xác định trong UIViewAnimationTransitionbảng liệt kê. Hiệu ứng làm mờ có thể đạt được bằng cách sử dụng CoreAnimation. Ví dụ mẫu cho phương pháp này:

#import <QuartzCore/QuartzCore.h>
...
imageView.image = [UIImage imageNamed:(i % 2) ? @"3.jpg" : @"4.jpg"];

CATransition *transition = [CATransition animation];
transition.duration = 1.0f;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade;

[imageView.layer addAnimation:transition forKey:nil];

2
Mã của bạn hoạt động hoàn hảo khi đi từ hình ảnh này sang hình ảnh khác. Bạn có biết làm thế nào để nó hoạt động với hình ảnh động tự động trong một UIImageView (thuộc tính animationImages) không?
CedricSoubrie

Bạn có thể thử sử dụng CAKeyFrameAnimation cho thuộc tính nội dung của lớp, mặc dù không chắc chắn nếu hiệu ứng sẽ giống nhau. Hoặc đặt đại biểu hoạt hình và trong chức năng gọi lại đại biểu bắt đầu hoạt ảnh sang hình ảnh tiếp theo khi hoạt ảnh trước kết thúc.
Vladimir

2
Điều này chắc chắn đơn giản hơn so với việc tạo hình thủ công cho một chế độ xem hình ảnh riêng biệt. Cảm ơn!
Kevlar

Chà .. Nếu khung hình xem thay đổi thì nó vẫn ở vị trí tương tự .. đó là một công cụ thỏa thuận!
hfossli

@Fossli, ý bạn là khi khung hình thay đổi trong khi hoạt hình? Đó là một câu hỏi khác sau đó
Vladimir

368
[UIView transitionWithView:textFieldimageView
                  duration:0.2f
                   options:UIViewAnimationOptionTransitionCrossDissolve
                animations:^{
                    imageView.image = newImage;
                } completion:nil];

là một khả năng khác


1
đơn giản và mở ra một loạt các hiệu ứng hoạt hình khác giữa các hình ảnh.
Vậy là hết

1
Có cùng một vấn đề mà @hfossli đã đề cập về thay đổi khung. Hoạt hình sẽ chậm chạp nếu bố cục được thay đổi trong thời gian đó.
Geva

1
Đây là giải pháp tốt nhất, bởi vì nó có thể được kết hợp với các hình ảnh động khác.
kelin

161

Theo lời của Michael Scott, hãy giữ cho nó đơn giản ngu ngốc. Đây là một cách đơn giản để làm điều này trong Swift 3Swift 4 :

UIView.transition(with: imageView,
                  duration: 0.75,
                  options: .transitionCrossDissolve,
                  animations: { self.imageView.image = toImage },
                  completion: nil)

3
Hoạt động như một lá bùa. Cảm ơn!
RobertoAllende

1
Uau tuyệt vời! Không biết về điều này quá lâu rồi :)
saveand

1
Điều này sẽ thay đổi thành 1 hình ảnh. Điều gì xảy ra nếu tôi có một loạt các hình ảnh và muốn hiển thị từng cái một với hình ảnh chuyển tiếp?
Ammar Mujeeb

1
Bạn có thể sử dụng khối hoàn thành để chuyển sang tiếp theo.
Zia

41

Dưới đây là một ví dụ trong Swift , đầu tiên sẽ hòa tan một hình ảnh mới và sau đó thêm một hình ảnh động nảy:

var selected: Bool {
  willSet(selected) {
    let expandTransform:CGAffineTransform = CGAffineTransformMakeScale(1.15, 1.15);
    if (!self.selected && selected) {
      UIView.transitionWithView(self.imageView,
        duration:0.1,
        options: UIViewAnimationOptions.TransitionCrossDissolve,
        animations: {
          self.imageView.image = SNStockCellSelectionAccessoryViewImage(selected)
          self.imageView.transform = expandTransform
        },
        completion: {(finished: Bool) in
          UIView.animateWithDuration(0.4,
            delay:0.0,
            usingSpringWithDamping:0.40,
            initialSpringVelocity:0.2,
            options:UIViewAnimationOptions.CurveEaseOut,
            animations: {
              self.imageView.transform = CGAffineTransformInvert(expandTransform)
            }, completion:nil)
      })
    }
  }
}

var imageView:UIImageView

Nếu imageViewđược thêm chính xác vào chế độ xem dưới dạng một khung nhìn phụ, chuyển đổi giữa selected = falseđể chuyển selected = trueđổi hình ảnh với một hình ảnh động nảy. SNStockCellSelectionAccessoryViewImagechỉ trả về một hình ảnh khác nhau dựa trên trạng thái lựa chọn hiện tại, xem bên dưới:

private let SNStockCellSelectionAccessoryViewPlusIconSelected:UIImage = UIImage(named:"PlusIconSelected")!
private let SNStockCellSelectionAccessoryViewPlusIcon:UIImage = UIImage(named:"PlusIcon")!

private func SNStockCellSelectionAccessoryViewImage(selected:Bool) -> UIImage {
  return selected ? SNStockCellSelectionAccessoryViewPlusIconSelected : SNStockCellSelectionAccessoryViewPlusIcon
}

Ví dụ GIF bên dưới bị chậm lại một chút, hoạt ảnh thực tế diễn ra nhanh hơn:

                                       Hoạt hình nảy UIImageView Gif


16

Mã số:

var fadeAnim:CABasicAnimation = CABasicAnimation(keyPath: "contents");

fadeAnim.fromValue = firstImage;
fadeAnim.toValue   = secondImage;
fadeAnim.duration  = 0.8;         //smoothest value

imageView.layer.addAnimation(fadeAnim, forKey: "contents");

imageView.image = secondImage;

Thí dụ:

Ví dụ UIImageView từ mã

Giải pháp thú vị, dài dòng hơn : (Đi bộ trên một vòi )

    let fadeAnim:CABasicAnimation = CABasicAnimation(keyPath: "contents");

    switch imageView.image {
        case firstImage?:
            fadeAnim.fromValue = firstImage;
            fadeAnim.toValue   = secondImage;
            imageView.image    = secondImage;
        default:
            fadeAnim.fromValue = secondImage;
            fadeAnim.toValue   = firstImage;
            imageView.image    = firstImage;
    }

    fadeAnim.duration = 0.8;

    imageView.layer.addAnimation(fadeAnim, forKey: "contents");

10

Thử cái này:

_imageView.image = image;
[_imageView.layer addAnimation:[CATransition animation] forKey:kCATransition];

swift: _imageView.layer.addAnimation (CATransition (), forKey: kCATransition)
Eugene Braginets

8

Với Swift 3

extension UIImageView{   
 var imageWithFade:UIImage?{
        get{
            return self.image
        }
        set{
            UIView.transition(with: self,
                              duration: 0.5, options: .transitionCrossDissolve, animations: {
                                self.image = newValue
            }, completion: nil)
        }
    }
}

Sử dụng:

myImageView.imageWithFade = myImage

6

Tại sao không thử điều này.

NSArray *animationFrames = [NSArray arrayWithObjects:
  [UIImage imageWithName:@"image1.png"],
  [UIImage imageWithName:@"image2.png"], 
  nil];

UIImageView *animatedImageView = [[UIImageView alloc] init];
animatedImageView.animationImages = animationsFrame;
[animatedImageView setAnimationRepeatCount:1];
[animatedImageView startAnimating];

Một phiên bản nhanh chóng:

let animationsFrames = [UIImage(named: "image1.png"), UIImage(named: "image2.png")]
let animatedImageView = UIImageView()
animatedImageView.animationImages = animationsFrames
animatedImageView.animationRepeatCount = 1
animatedImageView.startAnimating()

Điều này đặt UIImageView lặp đi lặp lại mãi mãi ... tác giả chỉ yêu cầu thay đổi tuy nhiên :(
J-Dizzle

setAnimationRepeatCount
William Hu

SetAnimationRepeatCount không thay đổi bất cứ điều gì. Nó không bao giờ dừng lại
Yucel Bayram

5
CABasicAnimation* fadeAnim = [CABasicAnimation animationWithKeyPath:@"contents"];
fadeAnim.fromValue = (__bridge id)imageView.image.CGImage;
fadeAnim.toValue = (__bridge id)[UIImage imageNamed:@"newImage.png"].CGImage;
fadeAnim.duration = 2.0;
[imageView.layer addAnimation:fadeAnim forKey:@"contents"];
imageView.layer.contents = (__bridge id)[UIImage imageNamed:@"newImage.png"].CGImage;

3

Có một vài cách tiếp cận khác nhau ở đây: UIAnimations đối với hồi ức của tôi nghe có vẻ như thách thức của bạn.

Chỉnh sửa: quá lười biếng của tôi :)

Trong bài đăng, tôi đã đề cập đến phương pháp này:

[newView setFrame:CGRectMake( 0.0f, 480.0f, 320.0f, 480.0f)]; //notice this is OFF screen!
[UIView beginAnimations:@"animateTableView" context:nil];
[UIView setAnimationDuration:0.4];
[newView setFrame:CGRectMake( 0.0f, 0.0f, 320.0f, 480.0f)]; //notice this is ON screen!
[UIView commitAnimations];

Nhưng thay vì tạo hiệu ứng cho khung hình, bạn tạo hiệu ứng alpha:

[newView setAlpha:0.0]; // set it to zero so it is all gone.
[UIView beginAnimations:@"animateTableView" context:nil];
[UIView setAnimationDuration:0.4];
[newView setAlpha:0.5]; //this will change the newView alpha from its previous zero value to 0.5f
[UIView commitAnimations];

2

Kể từ iOS 5, điều này dễ dàng hơn nhiều:

[newView setAlpha:0.0];
[UIView animateWithDuration:0.4 animations:^{
    [newView setAlpha:0.5];
}];

4
Điều đó không giúp ích gì cho vấn đề ban đầu, đó là bạn đã có một hình ảnh được hiển thị và muốn làm mờ dần sang một hình ảnh mới ...
Kendall Helmstetter Gelner

4
đúng .. câu trả lời này không giải quyết được câu hỏi. Câu hỏi không phải là làm thế nào để làm mờ dần trong hình ảnh tưởng tượng mà là làm mờ dần từ một hình ảnh cũ sang một hình ảnh mới. Các khối hoạt hình đã được giới thiệu trong iOS 4.
Bastian

2

Swift 4 Điều này thật tuyệt vời

  self.imgViewPreview.transform = CGAffineTransform(scaleX: 0, y: 0)
          UIView.animate(withDuration: 1, delay: 0, usingSpringWithDamping: 0.3, initialSpringVelocity: 0, options: .curveEaseOut, animations: {
              self.imgViewPreview.image = newImage
              self.imgViewPreview.transform = .identity
          }, completion: nil)

1

Câu trả lời của Vladimir là hoàn hảo, nhưng bất cứ ai như tôi, người đang tìm kiếm giải pháp nhanh chóng

Giải pháp này được làm việc cho phiên bản nhanh chóng 4.2

var i = 0
    func animation(){
        let name = (i % 2 == 0) ? "1.png" : "2.png"
        myImageView.image = UIImage.init(named: name)
        let transition: CATransition = CATransition.init()
        transition.duration = 1.0
        transition.timingFunction = CAMediaTimingFunction.init(name: .easeInEaseOut)
        transition.type = .fade
        myImageView.layer.add(transition, forKey: nil)
        i += 1
    }

Bạn có thể gọi phương pháp này từ bất cứ đâu. Nó sẽ thay đổi hình ảnh sang hình ảnh tiếp theo (hình ảnh) với hình ảnh động.

Đối với Swift Phiên bản 4.0 Sử dụng giải pháp dưới đây

var i = 0
    func animationVersion4(){
        let name = (i % 2 == 0) ? "1.png" : "2.png"
        uiImage.image = UIImage.init(named: name)
        let transition: CATransition = CATransition.init()
        transition.duration = 1.0
        transition.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut)
        transition.type = kCATransitionFade
        uiImage.layer.add(transition, forKey: nil)
        i += 1
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.