在 UIImageView 中的两个图像之间转换的最佳方法 [英] Best way to transition between two images in a UIImageView

查看:11
本文介绍了在 UIImageView 中的两个图像之间转换的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have implemented a pretty simple picture viewer that will allow the user to browse through a collection of images. They are loaded from the Internet, and displayed on the device through a UIImageView object. Something like this:

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

imageData 是我用来从 URL 加载图像内容的 NSData 的一个实例,而 img>UIImageView 实例.

imageData is an instance of NSData that I use to load the contents of the image from an URL, and img is the UIImageView instance.

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

It all works well, but the new image replaces the one being displayed before without any transitions, and I was wondering if there is an easy way to do a good animation transition to improve the user experience.

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

Any idea how to do this? Code samples would be very appreciated.

推荐答案

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

I was just going through your post and had exactly the same requirement. The problem with all above solutions is, you will have to incorporate the logic of transition into your controller. In the sense the approach is not modular. Instead I wrote this subclass of 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:]代码> 这样它就不会以无限递归调用结束!

You can even override the -setImage method of UIImageView and call my -setImage:withTransitionAnimation: method. If it is done like this make sure that you call [super setImage:] instead of [self setImage:] in the method -setImage:withTransitionAnimation: so that it wont end up in infinite recursive call!

-拉吉

这篇关于在 UIImageView 中的两个图像之间转换的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆