2008-10-17 4 views
19

Ich habe einen ziemlich einfachen Bildbetrachter implementiert, der es dem Benutzer ermöglicht, durch eine Sammlung von Bildern zu blättern. Sie werden aus dem Internet geladen und auf dem Gerät über ein UIImageView Objekt angezeigt. Etwas wie folgt aus:Der beste Weg zum Übergang zwischen zwei Bildern in einem UIImageView

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

imageData ist eine Instanz NSData, die ich benutze den Inhalt des Bildes von einer URL zu laden, und img ist die UIImageView Instanz.

Alles funktioniert gut, aber das neue Bild ersetzt das zuvor angezeigte Bild ohne Übergänge und ich frage mich, ob es einen einfachen Weg gibt, einen guten Animationsübergang zu machen, um das Benutzererlebnis zu verbessern.

Irgendeine Idee, wie man das macht? Codebeispiele würden sehr geschätzt werden.

+2

Für diejenigen von uns durchblättern wäre toll, wenn jemand eine Antwort auswählen könnte. Da dieser Benutzer scheinbar etwas vergessen hat ... – Mytheral

Antwort

3

Der Trick besteht darin, zwei UIImageView-Instanzen zu erstellen. Sie tauschen sie zwischen den Aufrufen von UIView + beginAnimations und + commitAnimations um.

1

Es gibt mehrere Möglichkeiten, dies zu tun, und ich stimme mit Ben View Transitions ist ein großartiges Beispiel. Wenn Sie nach einfachen Vollbildübergängen suchen, würde ich nur eine neue Utility-Anwendung starten und die toggleView-Methode im RootViewController.m betrachten. Versuchen Sie, die UIViewAnimationTransitionFlipFromLeft und UIViewAnimationTransitionFlipFromRight auf UIViewAnimationTransitionCurlUp und UIViewAnimationTransitionCurlDown für einen wirklich schönen Übergangseffekt zu schalten (dies funktioniert nur auf dem Gerät).

3

nichts anderes, als was im Code erklärt ist, aber das sind die verfügbaren Übergänge:

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

-Code(dies wie touchesEnded in einer Callback-Put):

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]; 
0

hier ist was ich getan habe: ein Verblassen. Ich legte eine andere UIImageView mit der gleichen UIImage und Dimension namens tmp. Ich ersetze die UIImage der Basis UIImageView. Dann lege ich das richtige Bild auf die Basis (immer noch von tmp bedeckt). Der nächste Schritt ist - um alpha von tmp auf Null zu setzen, - um das Basis-UIImageView-Verhältnis von der neuen UII zu verkleinern, basierend auf der Höhe der Basis. Hier

ist der Code:

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]; 
13

Ich war gerade durch Ihre Post zu gehen und hatte genau die gleiche Anforderung. Das Problem mit allen oben genannten Lösungen ist, dass Sie die Logik des Übergangs in Ihren Controller integrieren müssen. In dem Sinne ist der Ansatz nicht modular. Stattdessen schrieb ich diese Unterklasse von UIImageView:

TransitionImageView.h Datei:

#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-Datei:

#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 

Sie können sogar die -setImage Methode von UIImageView außer Kraft setzen und meine -setImage:withTransitionAnimation: Methode aufrufen. Wenn es so gemacht wird, stellen Sie sicher, dass Sie [super setImage:] anstelle von [self setImage:] in der Methode -setImage:withTransitionAnimation: aufrufen, so dass es nicht in unendlichen rekursiven Aufruf endet!

-Raj

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

Bitte überprüfen Sie die Antwort. Ich glaube, du bist auf der Suche nach diesem:

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]; 
+0

Dies funktioniert gut, besonders bei Push- und Transition-Subtypen. Ich denke, es ist die optimale Antwort, da es keine gefälschten Extra-Ansichten erstellen oder ihre Geometrie manipulieren muss. – SG1