我试图复制iPad上发生的书籍动画的放大和淡入淡出。基本上如果你还没有看到一本书放在书架上,当被轻拍时它会朝着屏幕的中心生长。当它接近屏幕的中心时,它会与您所在书籍的页面交叉淡化,无论是封面还是页面100.在iPhone上,书的封面朝屏幕中心增长,然后中途通过过渡,它会淡入您在书中所在的最后一页,并且缩放完成占据整个屏幕。
为了复制这个,我尝试做的是,有人点击我的collectionView。我得到该单元格的框架并截取该单元格的屏幕截图。我创建了一个内容为该图像的图层。
CALayer *smallLayer = [CALayer layer];
UIImage *smallImage = [UIImage renderImageFromView:self.smallZoomView];
smallLayer.frame = self.smallZoomRect;
smallLayer.contents = (__bridge id)smallImage.CGImage;
我将它添加到我用于动画的容器视图中。对于动画部分,我尝试了这个:
[CATransaction begin];
[CATransaction setAnimationDuration:5.0];
[CATransaction setDisableActions:YES];
CABasicAnimation *anim = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
anim.fromValue = [NSNumber numberWithFloat:1.0];
anim.toValue = [NSNumber numberWithFloat:2.0];
[self.smallZoomLayer addAnimation:anim forKey:@"Zoom"];
我的第一个问题是,无论动画从何处开始,如何让它朝着视图的中心增长。由于用户点击了一个集合视图单元格,它当前只是从该单元格的中心增长而不是向视图中心增长。
我的第二个问题是如何在我要展示的下一个屏幕上淡入淡出。我想我可以做这样的事情:How to crossfade between 2 images on iPhone using Core Animation以获得交叉渐变,但我不知道如何拍摄当前尚未显示的视图的截图。
有什么想法?如果这种方法有误,请告诉我!感谢。
答案 0 :(得分:1)
这是我工作的另一种方式。它不使用快照,而是缩放PageViewController的实际视图,将其添加为coverView下面的子视图,在containerView中,然后执行类似的动画。我不知道从“良好的编码实践”的角度来看这是否更好,但它只是展示了另一种方式(我一直在教自己这些东西,所以我正在尝试不同的选择)。 / p>
@interface ViewController ()
@property (strong,nonatomic) UIView *pageView;
@property (strong,nonatomic) PageController *pageVC;
@end
@implementation ViewController
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.pageVC = [self.storyboard instantiateViewControllerWithIdentifier:@"Page"]; // controller with the page contnent
self.pageView = self.pageVC.view;
self.pageView.transform = CGAffineTransformMakeScale(self.coverView.frame.size.width/self.pageView.frame.size.width, self.coverView.frame.size.height/self.pageView.frame.size.height);
[self.containerView insertSubview:self.pageView belowSubview:self.coverView];
[self.containerView constrainViewEqual:self.pageView];
}
-(IBAction)openCover:(id)sender {
self.coverView.layer.anchorPoint = CGPointMake(0, .5);
self.coverView.center = CGPointMake(self.coverView.center.x - self.coverView.frame.size.width/2, self.coverView.center.y);
[self.containerView removeConstraints:self.containerView.constraints];
[self.view removeConstraints:self.view.constraints];
[self.view constrainViewEqual:self.containerView];
[self.containerView constrainViewLeft:self.coverView];
[self.containerView constrainViewEqual:self.pageView];
NSInteger animationTime = 1;
[UIView animateWithDuration:animationTime animations:^{
self.pageView.transform = CGAffineTransformIdentity;
[self.view layoutIfNeeded];
}];
[UIView animateWithDuration:animationTime animations:^{
CATransform3D transform = CATransform3DIdentity;
transform =CATransform3DMakeRotation(M_PI_2, 0.0, -1.0, 0.0);
transform.m34 = 1/1000.0;
transform.m14 = -2/10000.0;
self.coverView.layer.transform =transform;
} completion:^(BOOL finished) {
[self.view.window addSubview:self.pageView];
[self.view.window setRootViewController:self.pageVC];
}];
}
答案 1 :(得分:0)
这是我尝试重新创建iBooks开放封面动画。我觉得它看起来很不错。 ViewController是初始控制器,在相同大小的UIView(pageView)中有一个图像视图(imageView),在我的例子中是90 x 122。 imageView有一个书籍封面的图像,我在另一个控制器的视图(FirstPageController)的快照的imageView下添加一个子视图 - 我有一个关于制作这些快照的问题,我看到你也发布了一个。我通过看起来像是一个黑客来解决它 - 我添加了FirstPageController的视图作为我的视图的子视图,做了快照,然后从我的视图中删除它。希望有人能提供更好的方法来实现这一目标。我使用NSLayoutConstraints进行了一些大小调整和居中,我在其他项目中使用了一个类别来保持代码分离。这是ViewController.m代码:
#import "ViewController.h"
#import "UIView+RDConstraintsAdditions.h"
#import <QuartzCore/QuartzCore.h>
#import "FirstPageController.h"
@interface ViewController ()
@property (strong,nonatomic) FirstPageController *fpController;
@end
@implementation ViewController
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
self.fpController = [self.storyboard instantiateViewControllerWithIdentifier:@"FirstPage"];
[self.view insertSubview:self.fpController.view belowSubview:self.view];
UIGraphicsBeginImageContext(self.fpController.view.bounds.size);
[self.fpController.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[self.fpController.view removeFromSuperview];
self.imageView2 = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 90, 122)];
self.imageView2.image = viewImage;
[self.pageView insertSubview:self.imageView2 belowSubview:self.imageView];
}
-(IBAction)expandImageView:(id)sender {
self.imageView.layer.anchorPoint = CGPointMake(0, .5);
self.imageView.center = CGPointMake(self.imageView.center.x - self.imageView.frame.size.width/2, self.imageView.center.y);
[self.view removeConstraints:self.view.constraints];
[self.pageView removeConstraints:self.pageView.constraints];
[self.view constrainViewEqual:self.pageView];
[self.pageView constrainViewLeft:self.imageView];
[self.pageView constrainViewEqual:self.imageView2];
[UIView animateWithDuration:2 animations:^{
[self.view layoutIfNeeded];
}];
[UIView animateWithDuration:2 animations:^{
CATransform3D transform = CATransform3DIdentity;
transform =CATransform3DMakeRotation(M_PI_2, 0.0, -1.0, 0.0);
transform.m34 = 1/1000.0;
transform.m14 = -2/10000.0;
self.imageView.layer.transform =transform;
} completion:^(BOOL finished) {
[self.view.window setRootViewController:self.fpController];
}];
}
以下是我使用的UIView类别:
#import "UIView+RDConstraintsAdditions.h"
@implementation UIView (RDConstraintsAdditions)
-(void)constrainViewEqual:(UIView *) view {
[view setTranslatesAutoresizingMaskIntoConstraints:NO];
NSLayoutConstraint *con1 = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterX relatedBy:0 toItem:view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
NSLayoutConstraint *con2 = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterY relatedBy:0 toItem:view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
NSLayoutConstraint *con3 = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:0 toItem:view attribute:NSLayoutAttributeWidth multiplier:1 constant:0];
NSLayoutConstraint *con4 = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:0 toItem:view attribute:NSLayoutAttributeHeight multiplier:1 constant:0];
NSArray *constraints = @[con1,con2,con3,con4];
[self addConstraints:constraints];
}
-(void)constrainViewLeft:(UIView *) view {
[view setTranslatesAutoresizingMaskIntoConstraints:NO];
NSLayoutConstraint *con1 = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeLeft relatedBy:0 toItem:view attribute:NSLayoutAttributeCenterX multiplier:1 constant:0];
NSLayoutConstraint *con2 = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeCenterY relatedBy:0 toItem:view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0];
NSLayoutConstraint *con3 = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeWidth relatedBy:0 toItem:view attribute:NSLayoutAttributeWidth multiplier:1 constant:0];
NSLayoutConstraint *con4 = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeHeight relatedBy:0 toItem:view attribute:NSLayoutAttributeHeight multiplier:1 constant:0];
NSArray *constraints = @[con1,con2,con3,con4];
[self addConstraints:constraints];
}
在动画结束时,我切换窗口的根视图控制器以获取“实时”FirstPageController视图而不是快照。