在UIImageView中两个图像之间转换的最佳方法

19 objective-c uiimageview ios

我已经实现了一个非常简单的图片查看器,允许用户浏览图像集合.它们从Internet加载,并通过UIImageView对象显示在设备上.像这样的东西:

UIImage *image = [[UIImage alloc] initWithData:imageData];
[img setImage:image];
Run Code Online (Sandbox Code Playgroud)

imageDataNSData我用来从URL加载图像内容imgUIImageView实例,并且是实例.

这一切都运行良好,但新图像替换之前显示的图像没有任何过渡,我想知道是否有一个简单的方法来做一个良好的动画过渡,以改善用户体验.

知道怎么做吗?代码样本将非常感激.

Raj*_*dal 13

我只是通过你的帖子,并有完全相同的要求.所有上述解决方案的问题在于,您必须将转换逻辑合并到控制器中.从某种意义上说,这种方法并非模块化.相反,我写了这个UIImageView的子类:

TransitionImageView.h文件:

#import <UIKit/UIKit.h>


@interface TransitionImageView : UIImageView 
{
    UIImageView *mOriginalImageViewContainerView;
    UIImageView *mIntermediateTransitionView;
}
@property (nonatomic, retain) UIImageView *originalImageViewContainerView;
@property (nonatomic, retain) UIImageView *intermediateTransitionView;

#pragma mark -
#pragma mark Animation methods
-(void)setImage:(UIImage *)inNewImage withTransitionAnimation:(BOOL)inAnimation;

@end
Run Code Online (Sandbox Code Playgroud)

TransitionImageView.m文件:

#import "TransitionImageView.h"

#define TRANSITION_DURATION 1.0

@implementation TransitionImageView
@synthesize intermediateTransitionView = mIntermediateTransitionView;
@synthesize originalImageViewContainerView = mOriginalImageViewContainerView;

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        // Initialization code
    }
    return self;
}

/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
    // Drawing code
}
*/

- (void)dealloc 
{
    [self setOriginalImageViewContainerView:nil];
    [self setIntermediateTransitionView:nil];
    [super dealloc];
}

#pragma mark -
#pragma mark Animation methods
-(void)setImage:(UIImage *)inNewImage withTransitionAnimation:(BOOL)inAnimation
{
    if (!inAnimation)
    {
        [self setImage:inNewImage];
    }
    else
    {
        // Create a transparent imageView which will display the transition image.
        CGRect rectForNewView = [self frame];
        rectForNewView.origin = CGPointZero;
        UIImageView *intermediateView = [[UIImageView alloc] initWithFrame:rectForNewView];
        [intermediateView setBackgroundColor:[UIColor clearColor]];
        [intermediateView setContentMode:[self contentMode]];
        [intermediateView setClipsToBounds:[self clipsToBounds]];
        [intermediateView setImage:inNewImage];

        // Create the image view which will contain original imageView's contents:
        UIImageView *originalView = [[UIImageView alloc] initWithFrame:rectForNewView];
        [originalView setBackgroundColor:[UIColor clearColor]];
        [originalView setContentMode:[self contentMode]];
        [originalView setClipsToBounds:[self clipsToBounds]];
        [originalView setImage:[self image]];

        // Remove image from the main imageView and add the originalView as subView to mainView:
        [self setImage:nil];
        [self addSubview:originalView];

        // Add the transparent imageView as subview whose dimensions are same as the view which holds it.
        [self addSubview:intermediateView];

        // Set alpha value to 0 initially:
        [intermediateView setAlpha:0.0];
        [originalView setAlpha:1.0];
        [self setIntermediateTransitionView:intermediateView];
        [self setOriginalImageViewContainerView:originalView];
        [intermediateView release];
        [originalView release];

        // Begin animations:
        [UIView beginAnimations:@"ImageViewTransitions" context:nil];
        [UIView setAnimationDuration:(double)TRANSITION_DURATION];
        [UIView setAnimationDelegate:self];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseOut];
        [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
        [[self intermediateTransitionView] setAlpha:1.0];
        [[self originalImageViewContainerView] setAlpha:0.0];
        [UIView commitAnimations];
    }
}

-(void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context
{
    // Reset the alpha of the main imageView
    [self setAlpha:1.0];

    // Set the image to the main imageView:
    [self setImage:[[self intermediateTransitionView] image]];

    [[self intermediateTransitionView] removeFromSuperview];
    [self setIntermediateTransitionView:nil];

    [[self originalImageViewContainerView] removeFromSuperview];
    [self setOriginalImageViewContainerView:nil];
}

@end
Run Code Online (Sandbox Code Playgroud)

您甚至可以覆盖-setImageUIImageView 的方法并调用我的-setImage:withTransitionAnimation:方法.如果这样做,请确保您调用[super setImage:]而不是[self setImage:]在方法中,-setImage:withTransitionAnimation:以便它不会以无限递归调用结束!

-Raj


neo*_*eye 8

[UIView 
    animateWithDuration:0.2 
    delay:0 
    options:UIViewAnimationCurveEaseOut
    animations:^{
        self.view0.alpha = 0;
        self.view1.alpha = 1;
    }
    completion:^(BOOL finished){
        view0.hidden = YES;
    }
];
Run Code Online (Sandbox Code Playgroud)


Chr*_*die 4

诀窍是创建两个 UIImageView 实例。您可以在对 UIView +beginAnimations 和 +commitAnimations 的调用之间交换它们。