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

我实现了一个非常简单的图片浏览器,可以让用户浏览一系列图片。 它们从网上加载,并通过UIImageView对象显示在设备上。 像这样的东西:

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

imageData是一个NSData的实例,我用来从URL加载图像的内容, imgUIImageView实例。

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

任何想法如何做到这一点? 代码示例将非常感激。

我只是通过你的post,并有完全相同的要求。 以上所有解决scheme的问题是,您将不得不将转换逻辑合并到您的控制器中。 在这个意义上说,这个方法不是模块化的 相反,我写了这个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:方法。 如果这样做,请确保在method -setImage:withTransitionAnimation:方法中调用[super setImage:]而不是[self setImage:] -setImage:withTransitionAnimation:以便它不会以无限recursion调用结束!

-Raj

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

诀窍是你做了两个UIImageView实例。 你在调用UIView + beginAnimations和+ commitAnimations之间交换它们。

与已经解释的代码没什么不同,这些是可用的转换:

 typedef enum { UIViewAnimationTransitionNone, UIViewAnimationTransitionFlipFromLeft, UIViewAnimationTransitionFlipFromRight, UIViewAnimationTransitionCurlUp, UIViewAnimationTransitionCurlDown, } UIViewAnimationTransition; 

代码 (把这个callback像touchesEnded一样)

 CGContextRef context = UIGraphicsGetCurrentContext(); [UIView beginAnimations:nil context:context]; [UIView setAnimationTransition: UIViewAnimationTransitionFlipFromLeft forView:[self superview] cache:YES]; // -- These don't work on the simulator and the curl up will turn into a fade -- // //[UIView setAnimationTransition: UIViewAnimationTransitionCurlUp forView:[self superview] cache:YES]; //[UIView setAnimationTransition: UIViewAnimationTransitionCurlDown forView:[self superview] cache:YES]; [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; [UIView setAnimationDuration:1.0]; // Below assumes you have two subviews that you're trying to transition between [[self superview] exchangeSubviewAtIndex:0 withSubviewAtIndex:1]; [UIView commitAnimations]; 

请检查答案。 我想你正在寻找这个:

 imgvw.image=[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"Your Image name as string"]]]; CATransition *transition = [CATransition animation]; transition.duration = 1.0f; transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; transition.type = kCATransitionFade; [imgvw.layer addAnimation:transition forKey:nil]; 

有几种方法可以做到这一点,我同意本视图转换是一个很好的例子。 如果您正在寻找简单的全屏转换,我只想考虑启动一个新的实用程序应用程序,并查看RootViewController.m中的toggleView方法。 尝试将UIViewAnimationTransitionFlipFromLeft和UIViewAnimationTransitionFlipFromRight切换到UIViewAnimationTransitionCurlUp和UIViewAnimationTransitionCurlDown,以获得非常好的过渡效果(这只适用于设备)。

这是我所做的:一个褪色。 我把另一个UIImageView与相同的UIImage和维度称为tmp。 我取代了UIImageView的UIImage。 然后,我把正确的形象在基地(仍由tmp覆盖)。

下一步是 – 将tmp的alpha设置为零, – 根据基底的高度将基本UIImageView拉伸到新UIImage的正确比例。

这里是代码:

  UIImage *img = [params objectAtIndex:0]; // the right image UIImageView *view = [params objectAtIndex:1]; // the base UIImageView *tmp = [[UIImageView alloc] initWithImage:view.image]; // the one which will use to fade tmp.frame = CGRectMake(0, 0, view.frame.size.width, view.frame.size.height); [view addSubview:tmp]; view.image = img; float r = img.size.width / img.size.height; float h = view.frame.size.height; float w = h * r; float x = view.center.x - w/2; float y = view.frame.origin.y; [UIView beginAnimations:nil context:nil]; [UIView setAnimationDuration:1.0]; tmp.alpha = 0; view.frame = CGRectMake(x, y, w, h); [UIView commitAnimations]; [tmp performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1.5]; [tmp performSelector:@selector(release) withObject:nil afterDelay:2];