Vertical Fold Animation

2019-06-02 18:51发布

问题:

I am trying to create fold animation for my UIView vertically.. After long search i found the following link.. Origami transition using CATransform3D perspective .. From the above link i just tried the following.. It gives me the exact animation.. By my UIView appears in reverse.. I dont know where i messed up.. Any help would be appreciated..

-(IBAction)animate
{


    CATransform3D transform = CATransform3DIdentity;
    CALayer *topSleeve;
    CALayer *middleSleeve;
    CALayer *topShadow;
    CALayer *middleShadow;
    UIView *mainView;
    CGFloat width = self.view.frame.size.width;
    CGFloat height = self.view.frame.size.height;
    CALayer *firstJointLayer;
    CALayer *secondJointLayer;
    CALayer *perspectiveLayer;

    mainView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, height)];
    mainView.backgroundColor = [UIColor clearColor];
    [self.view addSubview:mainView];

    UIGraphicsBeginImageContext(self.view.bounds.size);
    [self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();


    CGSize size = CGSizeMake(viewImage.size.width / 2, viewImage.size.height);


    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [[UIColor blackColor] CGColor]);
    CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height));
    UIImage *solidColorImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    // The left half of the image
    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
    [viewImage drawAtPoint:CGPointMake(0, 0) blendMode:kCGBlendModeNormal alpha:1.0];
    UIImage *leftImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();


    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
    [viewImage drawAtPoint:CGPointMake(-size.width, 0) blendMode:kCGBlendModeNormal alpha:1.0];
    [solidColorImage drawAtPoint:CGPointMake(0, 0) blendMode:kCGBlendModeMultiply alpha:0.1];
    UIImage *rightImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    perspectiveLayer = [CALayer layer];
    perspectiveLayer.frame = CGRectMake(0, 0, width/2, height);
    [mainView.layer addSublayer:perspectiveLayer];

    firstJointLayer = [CATransformLayer layer];
    firstJointLayer.frame = mainView.bounds;
    [perspectiveLayer addSublayer:firstJointLayer];

    topSleeve = [CALayer layer];
    topSleeve.frame = CGRectMake(0, 0, width/2, height);
    topSleeve.anchorPoint = CGPointMake(0, 0.5);
    topSleeve.backgroundColor = [UIColor colorWithPatternImage:leftImage].CGColor;
    topSleeve.position = CGPointMake(0, height/2);
    [firstJointLayer addSublayer:topSleeve];
    topSleeve.masksToBounds = YES;

    secondJointLayer = [CATransformLayer layer];
    secondJointLayer.frame = mainView.bounds;
    secondJointLayer.frame = CGRectMake(0, 0, width, height);
    secondJointLayer.anchorPoint = CGPointMake(0, 0.5);
    secondJointLayer.position = CGPointMake(width/2, height/2);
    [firstJointLayer addSublayer:secondJointLayer];

    middleSleeve = [CALayer layer];
    middleSleeve.frame = CGRectMake(0, 0, width/2, height);
    middleSleeve.anchorPoint = CGPointMake(0, 0.5);
    middleSleeve.backgroundColor = [UIColor colorWithPatternImage:rightImage].CGColor;
    middleSleeve.position = CGPointMake(0, height/2);
    [secondJointLayer addSublayer:middleSleeve];
    middleSleeve.masksToBounds = YES;


    firstJointLayer.anchorPoint = CGPointMake(0, 0.5);
    firstJointLayer.position = CGPointMake(0, height/2);

    topShadow = [CALayer layer];
    [topSleeve addSublayer:topShadow];
    topShadow.frame = topSleeve.bounds;
    topShadow.backgroundColor = [UIColor blackColor].CGColor;
    topShadow.opacity = 0.5;

    middleShadow = [CALayer layer];
    [middleSleeve addSublayer:middleShadow];
    middleShadow.frame = middleSleeve.bounds;
    middleShadow.backgroundColor = [UIColor blackColor].CGColor;
    middleShadow.opacity = 0.5;

    transform.m34 = 1.0/(-700.0);
    perspectiveLayer.sublayerTransform = transform;

    CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    [animation setDuration:2];
    [animation setAutoreverses:YES];
    [animation setRepeatCount:INFINITY];
    [animation setFromValue:[NSNumber numberWithDouble:90*M_PI/180]];
    [animation setToValue:[NSNumber numberWithDouble:0]];
    [firstJointLayer addAnimation:animation forKey:nil];

    animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
    [animation setDuration:2];
    [animation setAutoreverses:YES];
    [animation setRepeatCount:INFINITY];
    [animation setFromValue:[NSNumber numberWithDouble:-180*M_PI/180]];
    [animation setToValue:[NSNumber numberWithDouble:0]];
    [secondJointLayer addAnimation:animation forKey:nil];



    animation = [CABasicAnimation animationWithKeyPath:@"bounds.size.width"];
    [animation setDuration:2];
    [animation setAutoreverses:YES];
    [animation setRepeatCount:INFINITY];
    [animation setFromValue:[NSNumber numberWithDouble:perspectiveLayer.bounds.size.width]];
    [animation setToValue:[NSNumber numberWithDouble:0]];
    [perspectiveLayer addAnimation:animation forKey:nil];

    animation = [CABasicAnimation animationWithKeyPath:@"position.x"];
    [animation setDuration:2];
    [animation setAutoreverses:YES];
    [animation setRepeatCount:INFINITY];
    [animation setFromValue:[NSNumber numberWithDouble:perspectiveLayer.position.x]];
    [animation setToValue:[NSNumber numberWithDouble:0]];
    [perspectiveLayer addAnimation:animation forKey:nil];

    animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    [animation setDuration:2];
    [animation setAutoreverses:YES];
    [animation setRepeatCount:INFINITY];
    [animation setFromValue:[NSNumber numberWithDouble:0.5]];
    [animation setToValue:[NSNumber numberWithDouble:0]];
    [topShadow addAnimation:animation forKey:nil];

    animation = [CABasicAnimation animationWithKeyPath:@"opacity"];
    [animation setDuration:2];
    [animation setAutoreverses:YES];
    [animation setRepeatCount:INFINITY];
    [animation setFromValue:[NSNumber numberWithDouble:0.5]];
    [animation setToValue:[NSNumber numberWithDouble:0]];
    [middleShadow addAnimation:animation forKey:nil];

}

回答1:

This is because CALayer draws its background flipped. You'd better set each image to CALayer contents, which will draw each image as expected (not flipped). By the way, patterns with big images might increase memory usage, so you should avoid them.

topSleeve.contents = (id)leftImage.CGImage;
middleSleeve.contents = (id)rightImage.CGImage;