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

查看:64
本文介绍了在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 是<$ c的实例我用来从URL加载图像内容的$ c> NSData , img UIImageView instance。

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

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

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!

-Raj

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

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