2013-06-24 2 views
-1

я не знаю, как перевернуть мой UIView вертикально, у меня есть много точек зрения, и я каждый видКак создать вертикальную анимацию в iOS?

есть некоторые фотографии и их описание, я хочу вид флипа, как в книге, но не

слева право должно быть сверху вниз или снизу вверх,

я хочу, чтобы перевернуть всю страницу вертикально, как сверху вниз или снизу вверх,

как сделать этот вид работы в ИО?

им seraching на гугле но то не работает Я новичок в Развитию

Поэтому, пожалуйста, любезно кто может вести меня правильно, как я могу перевернуть мои взгляды Пожалуйста, Пожалуйста, помогите мне

из

Спасибо заранее.

+0

Может быть, это ссылка может помочь вам https: //www.cocoacontrols.com/controls/fliptransform – iCoder

ответ

1

Вы можете установить отрицательный масштаб, как:

[theView setTransform:CGAffineTransformMakeScale(1, -1)]; 
+0

@ Микаль вы можете предложить мне какой-нибудь простой учебник? –

+0

Не знаю никаких учебников по этому вопросу, но вы можете ознакомиться с документами здесь: https://developer.apple.com/library/mac/#documentation/graphicsimaging/reference/CGAffineTransform/Reference/reference.html – Mikael

+0

код должен быть [theView setTransform: CGAffineTransformMakeScale (1, -1)]; поскольку масштабирование до 0 приведет к исчезновению элемента – reza23

6

загрузить код из https://github.com/mtabini/AFKPageFlipper

и изменить AFKPageFlipper.h и AFKPageFlipper.m файл

// 
// 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 из AFKPageFlipper , я могу сделать вышеуказанный код .... кредит принадлежит г-ну мтабини (автор AFKPageFlipper)

+0

Спасибо, человек! это действительно помогло мне много +1! – xeravim

+0

не нужно приятелю. – Pradeep

0

То же Pradeep, но с тенями, а также ARC адаптированный:

AFKPageFlipper.h

// 
// 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; 

    // shadows 
    CALayer *frontLayerShadow; 
    CALayer *backLayerShadow; 
    CALayer *leftLayerShadow; 
    CALayer *rightLayerShadow; 
    // shadows 

    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.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,retain) UIView *currentView; 
@property (nonatomic,retain) 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); 

    [flipAnimationLayer addSublayer:frontLayer]; 

    // shadows 
    frontLayerShadow = [CALayer layer]; 
    frontLayerShadow.frame = frontLayer.bounds; 
    frontLayerShadow.doubleSided = NO; 
    frontLayerShadow.masksToBounds = YES; 
    frontLayerShadow.opacity = 0; 
    frontLayerShadow.backgroundColor = [UIColor blackColor].CGColor; 
    [frontLayer addSublayer:frontLayerShadow]; 

    backLayerShadow = [CALayer layer]; 
    backLayerShadow.frame = backLayer.bounds; 
    backLayerShadow.doubleSided = NO; 
    backLayerShadow.masksToBounds = YES; 
    backLayerShadow.opacity = 0; 
    backLayerShadow.backgroundColor = [UIColor blackColor].CGColor; 
    [backLayer addSublayer:backLayerShadow]; 


    leftLayerShadow = [CALayer layer]; 
    leftLayerShadow.frame = topLayer.bounds; 
    leftLayerShadow.doubleSided = NO; 
    leftLayerShadow.masksToBounds = YES; 
    leftLayerShadow.opacity = 0.0; 
    leftLayerShadow.backgroundColor = [UIColor blackColor].CGColor; 
    [topLayer addSublayer:leftLayerShadow]; 

    rightLayerShadow = [CALayer layer]; 
    rightLayerShadow.frame = bottomLayer.bounds; 
    rightLayerShadow.doubleSided = NO; 
    rightLayerShadow.masksToBounds = YES; 
    rightLayerShadow.opacity = 0.0; 
    rightLayerShadow.backgroundColor = [UIColor blackColor].CGColor; 
    [bottomLayer addSublayer:rightLayerShadow]; 
    // shadows 


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

    // shadows 
    //NSLog(@"End flip angle: %.0f, \tstartflip: %.0f, \tprogress: %.2f\tduration: %.2f", endFlipAngle, startFlipAngle,progress, duration); 
    CGFloat newShadowOpacity = (0.5 - progress); 

    if(newShadowOpacity < 0) { 
     newShadowOpacity *= -1; 
    } 
    if (newShadowOpacity < 0.05) { 
     newShadowOpacity = 0; 
    } 

    // shadows 

    if (duration < 0.15) { 
     duration = 0.15; 
    } 

    [UIView animateWithDuration: duration delay: 0 options: UIViewAnimationOptionCurveLinear animations: ^(void) { 
     flipAnimationLayer.transform = endTransform; 


     if (endFlipAngle < startFlipAngle) { 

      if(progress < 0.5) { 
       rightLayerShadow.opacity = newShadowOpacity; 
       frontLayerShadow.opacity = (0.5 - newShadowOpacity)/2; 

      } else { 
       backLayerShadow.opacity = (0.5 - newShadowOpacity)/2; 
       leftLayerShadow.opacity = newShadowOpacity; 
      } 

     } else { 
      if(progress < 0.5) { 
       leftLayerShadow.opacity = newShadowOpacity; 
       backLayerShadow.opacity = (0.5 - newShadowOpacity)/2; 


      } else { 
       frontLayerShadow.opacity = (0.5 - newShadowOpacity)/2; 
       rightLayerShadow.opacity = newShadowOpacity; 
      } 
     } 

     // shadows 
    } completion: ^(BOOL completion) { 

    }]; 


    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 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 = nil; 
    } 

    dataSource = value; 
    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])) { 
     [self initRecognizers]; 
    } 
    return self; 
} 

- (id)initWithCoder:(NSCoder *)aDecoder { 
    if ((self = [super initWithCoder: aDecoder])) { 
     [self initRecognizers]; 
    } 
    return self; 
} 

- (void) initRecognizers { 
    _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]; 
} 


@end 
+0

У меня возникла проблема с тем, что этот проект запускался в первый раз сверху вниз. И теперь я подправил фигуру донизу, она не перевернулась ... –