0

我试图复制发生在 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以获得交叉淡入淡出,但我不知道如何截取当前尚未显示的视图的屏幕截图。

有什么想法吗?如果这种方法是错误的,请告诉我!谢谢。

4

2 回答 2

1

这是我工作的另一种方式。它不使用快照,而是缩放 PageViewController 的实际视图,将其作为子视图添加到 coverView 下方,在 containerView 中,然后执行类似的动画。从“良好的编码实践”的角度来看,我不知道这是否更好,但它只是展示了另一种解决方法(我一直在自学这些东西,所以我正在尝试不同的替代方案)。

@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];
    }];
}
于 2012-12-22T00:28:01.947 回答
0

这是我重新创建 iBooks 打开封面动画的尝试。我觉得它看起来很不错。ViewController 是初始控制器,它在相同大小的 UIView (pageView) 内具有图像视图 (imageView),在我的示例中为 90 x 122。imageView 有一个书籍封面的图像,我在另一个控制器视图(FirstPageController)的快照的 imageView 下添加了一个子视图——我有一个关于制作这些快照的问题,我看到你也发布了一个。我通过看似 hack 的方式解决了它——我将 FirstPageController 的视图添加为我的视图的子视图,进行了快照,然后将其从我的视图中删除。希望有人会提供更好的方法来做到这一点。我使用 NSLayoutConstraints 进行了一些大小调整和居中,并且我有一个类别,我在其他项目中使用它来保持代码分离。

#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 视图而不是快照。

于 2012-12-21T06:53:39.970 回答