iOS Papel plegable (origami / acordeón) animation de efectos, con control manual

Estoy buscando consejos sobre cómo implementar el popular efecto de papel plegado / origami en mi proyecto iOS.

Soy consciente de proyectos como: https://github.com/xyfeng/XYOrigami pero solo ofrecen el efecto 'animado', sin control manual sobre la animation de apertura.

He luchado para diseccionar ese proyecto y encontrar lo que busco.

Para ser más exactos, estoy buscando cómo implementar el efecto que se muestra aquí: http://vimeo.com/41495357 donde la animation plegable no está simplemente animada abierta, sino que el usuario controla los pliegues de apertura.

Cualquier ayuda sería muy apreciada, gracias de antemano!

EDITAR:

Bien, aquí hay un código de ejemplo para ilustrar mejor con lo que estoy luchando:

Este método activa la animation del efecto de origami:

- (void)showOrigamiTransitionWith:(UIView *)view NumberOfFolds:(NSInteger)folds Duration:(CGFloat)duration Direction:(XYOrigamiDirection)direction completion:(void (^)(BOOL finished))completion { if (XY_Origami_Current_State != XYOrigamiTransitionStateIdle) { return; } XY_Origami_Current_State = XYOrigamiTransitionStateUpdate; //add view as parent subview if (![view superview]) { [[self superview] insertSubview:view belowSubview:self]; } //set frame CGRect selfFrame = self.frame; CGPoint anchorPoint; if (direction == XYOrigamiDirectionFromRight) { selfFrame.origin.x = self.frame.origin.x - view.bounds.size.width; view.frame = CGRectMake(self.frame.origin.x+self.frame.size.width-view.frame.size.width, self.frame.origin.y, view.frame.size.width, view.frame.size.height); anchorPoint = CGPointMake(1, 0.5); } else { selfFrame.origin.x = self.frame.origin.x + view.bounds.size.width; view.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, view.frame.size.width, view.frame.size.height); anchorPoint = CGPointMake(0, 0.5); } UIGraphicsBeginImageContext(view.frame.size); [view.layer renderInContext:UIGraphicsGetCurrentContext()]; UIImage *viewSnapShot = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); //set 3D depth CATransform3D transform = CATransform3DIdentity; transform.m34 = -1.0/800.0; CALayer *origamiLayer = [CALayer layer]; origamiLayer.frame = view.bounds; origamiLayer.backgroundColor = [UIColor colorWithWhite:0.2 alpha:1].CGColor; origamiLayer.sublayerTransform = transform; [view.layer addSublayer:origamiLayer]; //setup rotation angle double startAngle; CGFloat frameWidth = view.bounds.size.width; CGFloat frameHeight = view.bounds.size.height; CGFloat foldWidth = frameWidth/(folds*2); CALayer *prevLayer = origamiLayer; for (int b=0; b < folds*2; b++) { CGRect imageFrame; if (direction == XYOrigamiDirectionFromRight) { if(b == 0) startAngle = -M_PI_2; else { if (b%2) startAngle = M_PI; else startAngle = -M_PI; } imageFrame = CGRectMake(frameWidth-(b+1)*foldWidth, 0, foldWidth, frameHeight); } else { if(b == 0) startAngle = M_PI_2; else { if (b%2) startAngle = -M_PI; else startAngle = M_PI; } imageFrame = CGRectMake(b*foldWidth, 0, foldWidth, frameHeight); } CATransformLayer *transLayer = [self transformLayerFromImage:viewSnapShot Frame:imageFrame Duration:duration AnchorPiont:anchorPoint StartAngle:startAngle EndAngle:0]; [prevLayer addSublayer:transLayer]; prevLayer = transLayer; } [CATransaction begin]; [CATransaction setCompletionBlock:^{ self.frame = selfFrame; [origamiLayer removeFromSuperlayer]; XY_Origami_Current_State = XYOrigamiTransitionStateShow; if (completion) completion(YES); }]; [CATransaction setValue:[NSNumber numberWithFloat:duration] forKey:kCATransactionAnimationDuration]; CAAnimation *openAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position.x" function:openFunction fromValue:self.frame.origin.x+self.frame.size.width/2 toValue:selfFrame.origin.x+self.frame.size.width/2]; openAnimation.fillMode = kCAFillModeForwards; [openAnimation setRemovedOnCompletion:NO]; [self.layer addAnimation:openAnimation forKey:@"position"]; [CATransaction commit]; } 

El método toma una Capa CATransform de este método:

 - (CATransformLayer *)transformLayerFromImage:(UIImage *)image Frame:(CGRect)frame Duration:(CGFloat)duration AnchorPiont:(CGPoint)anchorPoint StartAngle:(double)start EndAngle:(double)end; { CATransformLayer *jointLayer = [CATransformLayer layer]; jointLayer.anchorPoint = anchorPoint; CGFloat layerWidth; if (anchorPoint.x == 0) //from left to right { layerWidth = image.size.width - frame.origin.x; jointLayer.frame = CGRectMake(0, 0, layerWidth, frame.size.height); if (frame.origin.x) { jointLayer.position = CGPointMake(frame.size.width, frame.size.height/2); } else { jointLayer.position = CGPointMake(0, frame.size.height/2); } } else { //from right to left layerWidth = frame.origin.x + frame.size.width; jointLayer.frame = CGRectMake(0, 0, layerWidth, frame.size.height); jointLayer.position = CGPointMake(layerWidth, frame.size.height/2); } //map image onto transform layer CALayer *imageLayer = [CALayer layer]; imageLayer.frame = CGRectMake(0, 0, frame.size.width, frame.size.height); imageLayer.anchorPoint = anchorPoint; imageLayer.position = CGPointMake(layerWidth*anchorPoint.x, frame.size.height/2); [jointLayer addSublayer:imageLayer]; CGImageRef imageCrop = CGImageCreateWithImageInRect(image.CGImage, frame); imageLayer.contents = (__bridge id)imageCrop; imageLayer.backgroundColor = [UIColor clearColor].CGColor; //add shadow NSInteger index = frame.origin.x/frame.size.width; double shadowAniOpacity; CAGradientLayer *shadowLayer = [CAGradientLayer layer]; shadowLayer.frame = imageLayer.bounds; shadowLayer.backgroundColor = [UIColor darkGrayColor].CGColor; shadowLayer.opacity = 0.0; shadowLayer.colors = [NSArray arrayWithObjects:(id)[UIColor blackColor].CGColor, (id)[UIColor clearColor].CGColor, nil]; if (index%2) { shadowLayer.startPoint = CGPointMake(0, 0.5); shadowLayer.endPoint = CGPointMake(1, 0.5); shadowAniOpacity = (anchorPoint.x)?0.24:0.32; } else { shadowLayer.startPoint = CGPointMake(1, 0.5); shadowLayer.endPoint = CGPointMake(0, 0.5); shadowAniOpacity = (anchorPoint.x)?0.32:0.24; } [imageLayer addSublayer:shadowLayer]; //animate open/close animation CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"]; [animation setDuration:duration]; [animation setFromValue:[NSNumber numberWithDouble:start]]; [animation setToValue:[NSNumber numberWithDouble:end]]; [animation setRemovedOnCompletion:NO]; [jointLayer addAnimation:animation forKey:@"jointAnimation"]; //animate shadow opacity animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; [animation setDuration:duration]; [animation setFromValue:[NSNumber numberWithDouble:(start)?shadowAniOpacity:0]]; [animation setToValue:[NSNumber numberWithDouble:(start)?0:shadowAniOpacity]]; [animation setRemovedOnCompletion:NO]; [shadowLayer addAnimation:animation forKey:nil]; return jointLayer; } 

Básicamente, necesito eliminar la animation automática y controlar el progreso del efecto usando algún valor configurado manualmente (por ejemplo: uislider value o offset de contenido).

¡Una vez más, cualquier ayuda proporcionada es muy apreciada!

Escribo otra biblioteca para doblar la transición: https://github.com/geraldhuard/YFoldView

Espero que funcione para ti.

Prueba esto. Tiene control de arrastre sobre el doblez del papel, lado izquierdo y derecho.

https://github.com/honcheng/PaperFold-for-iOS

Esta es la mejor solución que he visto:

http://api.mutado.com/mobile/paperstack/

EDITAR: ¿Qué pasa con esto: el efecto de plegado / deployment del papel en Twitter para iPad

    Intereting Posts