iOS纸张折叠(折纸/手风琴)效果动画,带手动控制

我正在寻找有关如何在我的iOS项目中实现流行的“纸张折叠/折纸”效果的提示。

我知道项目如: https : //github.com/xyfeng/XYOrigami但他们只提供’动画’效果,没有手动控制开场动画。

我一直在努力剖析那个项目并想出我所追求的目标。

更确切地说,我正在研究如何实现此处显示的效果: http : //vimeo.com/41495357 ,其中折叠动画不仅仅是动画打开,而是用户控制开始折叠。

任何帮助将非常感谢,提前感谢!

编辑:

好的,这里有一些示例代码可以更好地说明我正在努力解决的问题:

此方法触发折纸效果动画:

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

该方法从此方法中获取CATransform Layer:

 - (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; } 

基本上,我需要删除自动动画,并使用一些手动设置值(例如:uislider值或内容偏移量)来控制效果的进度。

再次提供任何帮助非常感谢!

我写了另一个用于折叠转换的库: https : //github.com/geraldhuard/YFoldView

希望对你有效。

尝试这个。 您可以控制纸张折叠,左侧和右侧。

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

这是我见过的最好的解决方案:

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

编辑:这个怎么样: Twitter上的纸张折叠/展开效果

Interesting Posts