2008-10-17 3 views
19

나는 사용자가 이미지 모음을 탐색 할 수있게 해주는 아주 간단한 그림 뷰어를 구현했습니다. 이들은 인터넷에서로드되어 UIImageView 개체를 통해 장치에 표시됩니다. 이런 식으로 뭔가가 :UIImageView에서 두 이미지 사이를 전환하는 가장 좋은 방법

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

imageData 내가 URL에서 이미지의 내용을로드하는 데 사용 NSData의 인스턴스이며, imgUIImageView 인스턴스입니다.

그것은 모두 잘 작동하지만 새로운 이미지는 전환하지 않고 이전에 표시되는 하나를 대체하고, 사용자 경험을 향상시킬 수있는 좋은 애니메이션 전환을 할 수있는 쉬운 방법이 있는지 궁금 해서요.

어떻게하면 좋을까요? 코드 샘플은 매우 감사하겠습니다.

+2

누군가가 대답을 선택할 수 있다면 우리를 뒤집어 쓰면 좋을 것입니다. 이 사용자는 몇 가지 방법을 남겨둔 것처럼 보입니다 ... – Mytheral

답변

3

트릭은 두 개의 UIImageView 인스턴스를 만드는 것입니다. UIView + beginAnimations와 + commitAnimations의 호출 사이를 전환합니다.

1

여러 가지 방법이 있으며 Ben View Transitions이 좋은 예입니다. 간단한 전체 화면 전환을 찾고 있다면 새로운 유틸리티 응용 프로그램을 시작하고 RootViewController.m에서 toggleView 메서드를 살펴보십시오. UIViewAnimationTransitionFlipFromLeft 및 UIViewAnimationTransitionFlipFromRight를 UIViewAnimationTransitionCurlUp 및 UIViewAnimationTransitionCurlDown으로 전환하여 정말 좋은 전환 효과를 얻으십시오.이 전환 효과는 기기에서만 작동합니다. 설명 있었는지에서하지만 코드에서이 가능한 전환 서로 다른

3

아무것도 :이 (touchesEnded 같은 콜백에 넣고)

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

코드 : 여기

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

내가 한 일은 바로 페이딩이다. 동일한 UIImage 및 tmp라는 차원을 가진 다른 UIImageView를 추가합니다. 기본 UIImageView의 UIImage를 바꿉니다. 그런 다음 기본 이미지 (여전히 tmp로 덮여 있음)에 올바른 이미지를 넣습니다.

다음 단계는 tmp의 알파를 0으로 설정하여 - 기준 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]; 
13

: 여기

는 코드입니다. 위의 모든 솔루션의 문제점은 컨트롤러로의 전환 논리를 통합해야한다는 것입니다. 의미에서 접근 방식은 모듈이 아니다.

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 대신 내가있는 UIImageView의 서브 클래스를 썼다.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: 메서드에서 [self setImage:] 대신 [super setImage:]을 호출하여 무한 재귀 호출로 끝나지 않도록하십시오!

-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

답을 확인하시기 바랍니다. 나는 당신이 이것을 찾고 있다고 생각합니다 :

+0

이것은 푸시 및 전환 하위 유형에서 특히 효과적입니다. 가짜 추가보기를 만들거나 지오메트리를 조작 할 필요가 없다는 점에서 최적의 답변이라고 생각합니다. – SG1

관련 문제