2008-10-17 9 views
19

Mam zaimplementowaną dość prostą przeglądarkę zdjęć, która pozwoli użytkownikowi przeglądać kolekcję obrazów. Są one ładowane z Internetu i wyświetlane na urządzeniu za pośrednictwem obiektu UIImageView. Coś takiego:Najlepszy sposób na przejście między dwoma obrazami w UIImageView

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

imageData jest instancją NSData że mogę używać, aby załadować zawartość obrazu z adresu URL, a img jest instancja UIImageView.

Wszystko działa dobrze, ale nowy obraz zastępuje obraz wyświetlany wcześniej bez żadnych przejść, i zastanawiałem się, czy istnieje łatwy sposób na zrobienie dobrego przejścia do animacji, aby poprawić wygodę użytkownika.

Każdy pomysł, jak to zrobić? Próbki kodu byłyby bardzo docenione.

+2

Dla tych z nas, którzy przeglądają to byłoby świetnie, gdyby ktoś mógł wybrać odpowiedź. Ponieważ ten użytkownik prawdopodobnie zostawił pewne ... – Mytheral

Odpowiedz

3

Podstęp polega na utworzeniu dwóch instancji UIImageView. Zamieniasz je pomiędzy rozmowami na UIView + beginAnimations i + commitAnimations.

1

Jest na to kilka sposobów i zgadzam się z Ben View Transitions, który jest świetnym przykładem. Jeśli szukasz prostych przejść na pełnym ekranie, chciałbym tylko rozważyć uruchomienie nowej aplikacji narzędziowej i przyjrzeć się metodzie toggleView w RootViewController.m. Spróbuj wyłączyć UIViewAnimationTransitionFlipFromLeft i UIViewAnimationTransitionFlipFromRight na UIViewAnimationTransitionCurlUp i UIViewAnimationTransitionCurlDown, aby uzyskać naprawdę niezły efekt przejścia (działa to tylko na urządzeniu).

3

Nic nie różni się od tego, co zostało wyjaśnione, ale w kodzie, to są dostępne przejścia:

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

Kod(umieścić to w zwrotnego jak 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]; 
0

tutaj jest to, co zrobiłem: blaknięcie. i umieścić inny UIImageView z tym samym UIImage i wymiar o nazwie tmp. Zamień UIImage podstawowego UIImageView. Następnie umieszczam odpowiedni obraz na bazie (nadal objęty tmp).

Kolejny krok to - aby ustawić wartość alfa tmp na zero, - aby rozciągnąć podstawowy UIImageView do prawego współczynnika nowego UIImage na podstawie wysokości podstawy.

Oto kod:

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

właśnie przeżywa swój post i miał dokładnie ten sam wymóg. Problem z wszystkimi powyższymi rozwiązaniami polega na tym, że musisz wprowadzić logikę przejścia do kontrolera. W tym sensie podejście nie jest modułowe. Zamiast Napisałem ten podklasa UIImageView: Plik

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 file:

#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 

Można nawet zastąpić metodę UIImageView -setImage i zadzwonić do mojego sposobu -setImage:withTransitionAnimation:. Jeśli jest to zrobione w ten sposób, upewnij się, że wywołujesz [super setImage:] zamiast [self setImage:] w metodzie -setImage:withTransitionAnimation:, aby nie zakończyło się nieskończoną rekurencją!

-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

Proszę sprawdzić odpowiedź. Myślę, że tego szukasz:

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

To działa dobrze, szczególnie w przypadku podtypów typu "push" i "transition". Myślę, że jest to optymalna odpowiedź, ponieważ nie wymaga tworzenia fałszywych dodatkowych widoków ani manipulowania ich geometrią. – SG1

Powiązane problemy