如何在ios中创建垂直翻转视图动画? [英] How can i create vertical Flip View Animation in ios?

查看:152
本文介绍了如何在ios中创建垂直翻转视图动画?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我不知道如何垂直翻转我的uiview,我有很多视图,而且我的每个视图

I don't know how to flip my uiview vertically , i have many views and i every view

有一些照片及其描述,我想翻转查看就像一本书而不是

there are some photos and their description, i want a flip view like a book but not

从左到右它必须是从上到下或从下到上,

left to right it must be top to bottom or bottom to top,

我想垂直翻转整个页面,如从上到下或从下到上,

i want to flip the whole page vertically like top to bottom or bottom to top,

如何在ios中完成这类工作?

how to do this kind of work in ios ?

我正在谷歌上搜索但这不起作用我是开发中的新手

i m seraching on google but thats not working i'm new in developement

所以请任何人都可以正确指导我如何翻转我的观点请帮助我

So please kindly anyone can guide me properly how can i flip my views Please Please help me

out

提前致谢。

推荐答案

https://github.com/mtabini下载代码/ AFKPageFlipper

并更改AFKPageFlipper.h和AFKPageFlipper.m文件

and change the AFKPageFlipper.h and AFKPageFlipper.m file

//
//  AFKPageFlipper.h
//  AFKPageFlipper
//
//  Created by Marco Tabini on 10-10-11.
//  Copyright 2010 AFK Studio Partnership. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>


@class AFKPageFlipper;


@protocol AFKPageFlipperDataSource

- (NSInteger) numberOfPagesForPageFlipper:(AFKPageFlipper *) pageFlipper;
- (UIView *) viewForPage:(NSInteger) page inFlipper:(AFKPageFlipper *) pageFlipper;

@end


typedef enum {
    AFKPageFlipperDirectionTop,
    AFKPageFlipperDirectionBottom,
} AFKPageFlipperDirection;



@interface AFKPageFlipper : UIView {
    NSObject <AFKPageFlipperDataSource> *dataSource;
    NSInteger currentPage;
    NSInteger numberOfPages;

    UIView *currentView;
    UIView *nextView;

    CALayer *backgroundAnimationLayer;
    CALayer *flipAnimationLayer;

    AFKPageFlipperDirection flipDirection;
    float startFlipAngle;
    float endFlipAngle;
    float currentAngle;

    BOOL setNextViewOnCompletion;
    BOOL animating;

    BOOL disabled;
}

@property (nonatomic,retain) NSObject <AFKPageFlipperDataSource> *dataSource;
@property (nonatomic,assign) NSInteger currentPage;

@property (nonatomic, retain) UITapGestureRecognizer *tapRecognizer;
@property (nonatomic, retain) UIPanGestureRecognizer *panRecognizer;

@property (nonatomic,assign) BOOL disabled;

- (void) setCurrentPage:(NSInteger) value animated:(BOOL) animated;

@end







//
//  AFKPageFlipper.m
//  AFKPageFlipper
//
//  Created by Marco Tabini on 10-10-12.
//  Copyright 2010 AFK Studio Partnership. All rights reserved.
//

#import "AFKPageFlipper.h"



#pragma mark -
#pragma mark UIView helpers


@interface UIView(Extended) 

- (UIImage *) imageByRenderingView;

@end


@implementation UIView(Extended)


- (UIImage *) imageByRenderingView {
    CGFloat oldAlpha = self.alpha;
    self.alpha = 1;
    UIGraphicsBeginImageContext(self.bounds.size);
    [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    self.alpha = oldAlpha;
    return resultingImage;
}

@end


#pragma mark -
#pragma mark Private interface


@interface AFKPageFlipper()

@property (nonatomic,assign) UIView *currentView;
@property (nonatomic,assign) UIView *nextView;

@end


@implementation AFKPageFlipper

@synthesize tapRecognizer = _tapRecognizer;
@synthesize panRecognizer = _panRecognizer;


#pragma mark -
#pragma mark Flip functionality


- (void) initFlip {

    // Create screenshots of view

    UIImage *currentImage = [self.currentView imageByRenderingView];
    UIImage *newImage = [self.nextView imageByRenderingView];

    // Hide existing views

    self.currentView.alpha = 0;
    self.nextView.alpha = 0;

    // Create representational layers

    CGRect rect = self.bounds;
    rect.size.height /= 2;

    backgroundAnimationLayer = [CALayer layer];
    backgroundAnimationLayer.frame = self.bounds;
    backgroundAnimationLayer.zPosition = -300000;

    CALayer *topLayer = [CALayer layer];
    topLayer.frame = rect;
    topLayer.masksToBounds = YES;
    topLayer.contentsGravity = kCAGravityBottom;

    [backgroundAnimationLayer addSublayer:topLayer];

    rect.origin.y = rect.size.height;

    CALayer *bottomLayer = [CALayer layer];
    bottomLayer.frame = rect;
    bottomLayer.masksToBounds = YES;
    bottomLayer.contentsGravity = kCAGravityTop;

    [backgroundAnimationLayer addSublayer:bottomLayer];

    if (flipDirection == AFKPageFlipperDirectionBottom) {
        topLayer.contents = (id) [newImage CGImage];
        bottomLayer.contents = (id) [currentImage CGImage];
    } else {
        topLayer.contents = (id) [currentImage CGImage];
        bottomLayer.contents = (id) [newImage CGImage];
    }

    [self.layer addSublayer:backgroundAnimationLayer];

    rect.origin.y = 0;

    flipAnimationLayer = [CATransformLayer layer];
    flipAnimationLayer.anchorPoint = CGPointMake(0.5, 1);
    flipAnimationLayer.frame = rect;

    [self.layer addSublayer:flipAnimationLayer];

    CALayer *backLayer = [CALayer layer];
    backLayer.frame = flipAnimationLayer.bounds;
    backLayer.doubleSided = NO;
    backLayer.masksToBounds = YES;

    [flipAnimationLayer addSublayer:backLayer];

    CALayer *frontLayer = [CALayer layer];
    frontLayer.frame = flipAnimationLayer.bounds;
    frontLayer.doubleSided = NO;
    frontLayer.masksToBounds = YES;

    frontLayer.transform = CATransform3DMakeRotation(M_PI, 1.0, 0.0, 0);

    [flipAnimationLayer addSublayer:frontLayer];

    if (flipDirection == AFKPageFlipperDirectionBottom) {
        backLayer.contents = (id) [currentImage CGImage];
        backLayer.contentsGravity = kCAGravityBottom;

        frontLayer.contents = (id) [newImage CGImage];
        frontLayer.contentsGravity = kCAGravityTop;

        CATransform3D transform = CATransform3DMakeRotation(1.1/M_PI, 1.0, 0.0, 0.0);
        transform.m34 = 1.0f / 2500.0f;

        flipAnimationLayer.transform = transform;

        currentAngle = startFlipAngle = 0;
        endFlipAngle = M_PI;
    } else {
        //down
        backLayer.contents = (id) [newImage CGImage];
        backLayer.contentsGravity = kCAGravityBottom;

        frontLayer.contents = (id) [currentImage CGImage];
        frontLayer.contentsGravity = kCAGravityTop;

        CATransform3D transform = CATransform3DMakeRotation(M_PI/1.1, 1.0, 0.0, 0.0);
        transform.m34 = 1.0f / 2500.0f;

        flipAnimationLayer.transform = transform;

        currentAngle = startFlipAngle = M_PI;
        endFlipAngle = 0;
    }
}


- (void) cleanupFlip {
    [backgroundAnimationLayer removeFromSuperlayer];
    [flipAnimationLayer removeFromSuperlayer];

    backgroundAnimationLayer = Nil;
    flipAnimationLayer = Nil;

    animating = NO;

    if (setNextViewOnCompletion) {
        [self.currentView removeFromSuperview];
        self.currentView = self.nextView;
        self.nextView = Nil;
    } else {
        [self.nextView removeFromSuperview];
        self.nextView = Nil;
    }

    self.currentView.alpha = 1;
}


- (void) setFlipProgress:(float) progress setDelegate:(BOOL) setDelegate animate:(BOOL) animate {
    if (animate) {
        animating = YES;
    }

    float newAngle = startFlipAngle + progress * (endFlipAngle - startFlipAngle);

    float duration = animate ? 0.5 * fabs((newAngle - currentAngle) / (endFlipAngle - startFlipAngle)) : 0;

    currentAngle = newAngle;

    CATransform3D endTransform = CATransform3DIdentity;
    endTransform.m34 = 1.0f / 2500.0f;
    endTransform = CATransform3DRotate(endTransform, newAngle, 1.0, 0.0, 0.0);

    [flipAnimationLayer removeAllAnimations];

    [CATransaction begin];
    [CATransaction setAnimationDuration:duration];

    flipAnimationLayer.transform = endTransform;

    [CATransaction commit];

    if (setDelegate) {
        [self performSelector:@selector(cleanupFlip) withObject:Nil afterDelay:duration];
    }
}


- (void) flipPage {
    [self setFlipProgress:1.0 setDelegate:YES animate:YES];
}


#pragma mark -
#pragma mark Animation management


- (void)animationDidStop:(NSString *) animationID finished:(NSNumber *) finished context:(void *) context {
    [self cleanupFlip];
}


#pragma mark -
#pragma mark Properties

@synthesize currentView;


- (void) setCurrentView:(UIView *) value {
    if (currentView) {
        [currentView release];
    }

    currentView = [value retain];
}


@synthesize nextView;


- (void) setNextView:(UIView *) value {
    if (nextView) {
        [nextView release];
    }

    nextView = [value retain];
}


@synthesize currentPage;


- (BOOL) doSetCurrentPage:(NSInteger) value {
    if (value == currentPage) {
        return FALSE;
    }

    flipDirection = value < currentPage ? AFKPageFlipperDirectionBottom : AFKPageFlipperDirectionTop;

    currentPage = value;

    self.nextView = [self.dataSource viewForPage:value inFlipper:self];
    [self addSubview:self.nextView];

    return TRUE;
}   

- (void) setCurrentPage:(NSInteger) value {
    if (![self doSetCurrentPage:value]) {
        return;
    }

    setNextViewOnCompletion = YES;
    animating = YES;

    self.nextView.alpha = 0;

    [UIView beginAnimations:@"" context:Nil];
    [UIView setAnimationDuration:0.5];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];

    self.nextView.alpha = 1;

    [UIView commitAnimations];
} 


- (void) setCurrentPage:(NSInteger) value animated:(BOOL) animated {
    if (![self doSetCurrentPage:value]) {
        return;
    }

    setNextViewOnCompletion = YES;
    animating = YES;

    if (animated) {
        [self initFlip];
        [self performSelector:@selector(flipPage) withObject:Nil afterDelay:0.091];
    } else {
        [self animationDidStop:Nil finished:[NSNumber numberWithBool:NO] context:Nil];
    }

}


@synthesize dataSource;


- (void) setDataSource:(NSObject <AFKPageFlipperDataSource>*) value {
    if (dataSource) {
        [dataSource release];
    }

    dataSource = [value retain];
    numberOfPages = [dataSource numberOfPagesForPageFlipper:self];
    currentPage = 0;
    self.currentPage = 1;
}


@synthesize disabled;


- (void) setDisabled:(BOOL) value {
    disabled = value;

    self.userInteractionEnabled = !value;

    for (UIGestureRecognizer *recognizer in self.gestureRecognizers) {
        recognizer.enabled = !value;
    }
}


#pragma mark -
#pragma mark Touch management


- (void) tapped:(UITapGestureRecognizer *) recognizer {
    if (animating || self.disabled) {
        return;
    }

    if (recognizer.state == UIGestureRecognizerStateRecognized) {
        NSInteger newPage;

        if ([recognizer locationInView:self].y < (self.bounds.size.height - self.bounds.origin.y) / 2) {
            newPage = MAX(1, self.currentPage - 1);
        } else {
            newPage = MIN(self.currentPage + 1, numberOfPages);
        }

        [self setCurrentPage:newPage animated:YES];
    }
}


- (void) panned:(UIPanGestureRecognizer *) recognizer {
    if (animating) {
        return;
    }

    static BOOL hasFailed;
    static BOOL initialized;

    static NSInteger oldPage;



    float translation = [recognizer translationInView:self].y;


    float progress = translation / self.bounds.size.height;


    if (flipDirection == AFKPageFlipperDirectionTop) {
        progress = MIN(progress, 0);
    } else {
        progress = MAX(progress, 0);
    }

    switch (recognizer.state) {
        case UIGestureRecognizerStateBegan:
            hasFailed = FALSE;
            initialized = FALSE;
            animating = NO;
            setNextViewOnCompletion = NO;
            break;


        case UIGestureRecognizerStateChanged:

            if (hasFailed) {
                return;
            }

            if (!initialized) {
                oldPage = self.currentPage;

                if (translation > 0) {
                    if (self.currentPage > 1) {
                        [self doSetCurrentPage:self.currentPage - 1];
                    } else {
                        hasFailed = TRUE;
                        return;
                    }
                } else {
                    if (self.currentPage < numberOfPages) {
                        [self doSetCurrentPage:self.currentPage + 1];
                    } else {
                        hasFailed = TRUE;
                        return;
                    }
                }

                hasFailed = NO;
                initialized = TRUE;
                setNextViewOnCompletion = NO;

                [self initFlip];
            }

            [self setFlipProgress:fabs(progress) setDelegate:NO animate:NO];

            break;


        case UIGestureRecognizerStateFailed:
            [self setFlipProgress:0.0 setDelegate:YES animate:YES];
            currentPage = oldPage;
            break;

        case UIGestureRecognizerStateRecognized:
            if (hasFailed) {
                [self setFlipProgress:0.0 setDelegate:YES animate:YES];
                currentPage = oldPage;

                return;
            }

            if (fabs((translation + [recognizer velocityInView:self].y / 4) / self.bounds.size.height) > 0.5) {
                setNextViewOnCompletion = YES;
                [self setFlipProgress:1.0 setDelegate:YES animate:YES];
            } else {
                [self setFlipProgress:0.0 setDelegate:YES animate:YES];
                currentPage = oldPage;
            }

            break;
        default:
            break;
    }
}


#pragma mark -
#pragma mark Frame management


- (void) setFrame:(CGRect) value {
    super.frame = value;

    numberOfPages = [dataSource numberOfPagesForPageFlipper:self];

    if (self.currentPage > numberOfPages) {
        self.currentPage = numberOfPages;
    }

}


#pragma mark -
#pragma mark Initialization and memory management


+ (Class) layerClass {
    return [CATransformLayer class];
}

- (id)initWithFrame:(CGRect)frame {
    if ((self = [super initWithFrame:frame])) {
        _tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapped:)];
        _panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panned:)];

        [_tapRecognizer requireGestureRecognizerToFail:_panRecognizer];

        [self addGestureRecognizer:_tapRecognizer];
        [self addGestureRecognizer:_panRecognizer];
    }
    return self;
}


- (void)dealloc {
    self.dataSource = Nil;
    self.currentView = Nil;
    self.nextView = Nil;
    self.tapRecognizer = Nil;
    self.panRecognizer = Nil;
    [super dealloc];
}


@end

becoz of AFKPageFlipper,我能够做上面的代码....功劳归于mtabini先生(AFKPageFlipper作者)

becoz of AFKPageFlipper, i am able to do the above code....credit goes to Mr. mtabini ( AFKPageFlipper author )

这篇关于如何在ios中创建垂直翻转视图动画?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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