ios - 在 UIImageView 中的两个图像之间转换的最佳方式

标签 ios objective-c uiimageview

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

UIImage *image = [[UIImage alloc] initWithData:imageData];
[img setImage:image];

imageDataNSData 的实例,我用它从 URL 加载图像的内容,而 imgUIImageView 实例。

一切正常,但新图像取代了之前显示的图像,没有任何过渡,我想知道是否有一种简单的方法可以进行良好的动画过渡以改善用户体验。

知道怎么做吗?代码示例将不胜感激。

最佳答案

我刚刚浏览了您的帖子并且有完全相同的要求。上述所有解决方案的问题是,您必须将转换逻辑合并到您的 Controller 中。从某种意义上说,该方法不是模块化的。相反,我写了这个 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

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

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

-拉吉

关于ios - 在 UIImageView 中的两个图像之间转换的最佳方式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/212689/

相关文章:

iphone - 有条件地包含用于不同 iOS SDK 版本的库?

iphone - 如何在饼图上显示文本?

iphone - Xcode 项目中有两个相同的文件名

ios - 堆栈 View ScaleAspectFit 蒙版在 Swift 中调整大小

swift - 如何在单击按钮时在 ImageView 中显示不同的图像

iOS:plist 中需要 Retina 显示

iphone - 单击作为 subview 添加到 UILabel 的 UIButton 将打开远离按钮的弹出窗口。?

ios - 为什么我的对象会发生意外变化?

iphone - Objective c 如何根据图像大小缩放 ImageView 大小(高度)

ios - 确定实际屏幕/舞台分辨率的 Flex 4.5 Mobile iOS 问题