动画UIView将一半折叠到另一半

时间:2011-12-15 14:52:02

标签: objective-c ios ipad calayer caanimation

我有以下问题。 我想写一个方法,用它可以将UIView的一半折叠到另一半上。

算法对我来说很清楚(至少我是这么认为的,但也许我忘记了一些事情)。

  1. 创建UIView的渲染图像
  2. 根据我想要折叠到另一半
  3. 的一半来分割它
  4. 将渲染图像的相应半部分添加到相应的图层
  5. 将两个图层添加到背景图层,背景图层为白色背景,没有内容(只是在那里制作白色背景以遮盖视图的原始图层)
  6. 将背景图层添加到视图图层
  7. 设置折叠图层的转换
  8. 启动动画
  9. 应该工作,但不是!我不明白为什么。 :(

    以下是方法的源代码:

    -(void)foldView:(UIView *) view withDuration: (NSTimeInterval) duration toSide: (NSString*) side withReverse: (bool) reverse andRepeatCount:(float) repeatCount
    {
        //create Screenshot from view to fold
        UIGraphicsBeginImageContext(view.bounds.size);
        [view.layer renderInContext:UIGraphicsGetCurrentContext()];
        UIImage *img_view = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        //Bildausschnitte festlegen
        CGRect rect_closingImageHalf = view.bounds;    
        CGRect rect_fixedImageHalf = view.bounds;    
    
        CGPoint pt_anchorOpeningImageHalf;
        CGPoint pt_anchorFixedImageHalf;
    
        CATransform3D transform;
    
        CALayer *lay_closingImageHalf;
        CALayer *lay_fixedImageHalf;
        lay_fixedImageHalf.masksToBounds = YES;
        lay_closingImageHalf.masksToBounds = YES;
        //get white backside of layer which folds
        lay_closingImageHalf.doubleSided = NO;
    
    
        //white backgroundlayer to hide the layer of the image
        CALayer *backgroundAnimationLayer = [CALayer layer];
        backgroundAnimationLayer.frame = view.frame;
        backgroundAnimationLayer.backgroundColor = [[UIColor whiteColor] CGColor];
    
        //determine direction in which to fold    
        if ([side isEqualToString:k_side_vonLinks]) 
        {
            rect_closingImageHalf = CGRectMake(0, 0, img_view.size.width / 2, img_view.size.height);
            rect_fixedImageHalf = CGRectMake(img_view.size.width / 2, 0, img_view.size.width / 2, img_view.size.height);
    
            pt_anchorOpeningImageHalf = CGPointMake(1.0, 0.5);        
            pt_anchorFixedImageHalf = CGPointMake(0.5, 0.5);
    
            transform = CATransform3DMakeRotation(M_PI, 0, 1.0, 0);
        }
        else if([side isEqualToString:k_side_vonRechts])
        {
            rect_closingImageHalf = CGRectMake(img_view.size.width / 2, 0, img_view.size.width / 2, img_view.size.height);
            rect_fixedImageHalf = CGRectMake(0, 0, img_view.size.width / 2, img_view.size.height);
    
            pt_anchorOpeningImageHalf = CGPointMake(0.0, 0.5);
            pt_anchorFixedImageHalf = CGPointMake(0.5, 0.5);   
    
            transform = CATransform3DMakeRotation(M_PI, 0, 1.0, 0);
        }
        else if([side isEqualToString:k_side_vonOben])
        {
            rect_closingImageHalf = CGRectMake(0, 0, img_view.size.width, img_view.size.height / 2);
            rect_fixedImageHalf = CGRectMake(0, img_view.size.height / 2, img_view.size.width, img_view.size.height / 2);
    
            pt_anchorOpeningImageHalf = CGPointMake(0.5, 1.0);
            pt_anchorFixedImageHalf = CGPointMake(0.5, 0.5);
    
            transform = CATransform3DMakeRotation(M_PI, 1.0, 0, 0);
        }
        else if([side isEqualToString:k_side_vonUnten])
        {
            rect_closingImageHalf = CGRectMake(0, img_view.size.height / 2, img_view.size.width, img_view.size.height / 2);
            rect_fixedImageHalf = CGRectMake(0, 0, img_view.size.width, img_view.size.height / 2);
    
            pt_anchorOpeningImageHalf = CGPointMake(0.5, 0.0);
            pt_anchorFixedImageHalf = CGPointMake(0.5, 0.5);
    
            transform = CATransform3DMakeRotation(M_PI, 1.0, 0, 0);
        }
    
        CGImageRef img_closingHalf = CGImageCreateWithImageInRect( [img_view CGImage], rect_closingImageHalf);
        CGImageRef img_fixedHalf = CGImageCreateWithImageInRect( [img_view CGImage], rect_fixedImageHalf);    
    
        lay_closingImageHalf.anchorPoint = pt_anchorOpeningImageHalf;
        lay_fixedImageHalf.anchorPoint = pt_anchorFixedImageHalf;
    
    
        //add the rendered image of the view to the backgroundLayer
        [backgroundAnimationLayer addSublayer:lay_fixedImageHalf];
        [backgroundAnimationLayer addSublayer:lay_closingImageHalf];
        lay_closingImageHalf.contents = (__bridge id)img_closingHalf;
        lay_fixedImageHalf.contents = (__bridge id)img_fixedHalf;
    
    
        [view.layer addSublayer:backgroundAnimationLayer];
    
        //add perspective
        transform.m34 = 1.0f / 2500.0f;
    
        //animate the folding of the layer
        CABasicAnimation *flipAnimation = [CABasicAnimation animationWithKeyPath:@"transform"];
        flipAnimation.toValue = [NSValue valueWithCATransform3D:transform];
        flipAnimation.duration = duration;
        flipAnimation.autoreverses = reverse;
        flipAnimation.repeatCount = repeatCount;
        flipAnimation.delegate = self;
        flipAnimation.removedOnCompletion = NO;
        flipAnimation.fillMode = kCAFillModeForwards;
    
        [backgroundAnimationLayer addAnimation:flipAnimation forKey:@"fold"];
    }
    

    如果有人知道为什么它不起作用,我会很高兴,如果他能提供帮助。 我用谷歌搜索了近一天,读了很多样本​​,但我找不到错误。 我也查看了AFKPageFLipper这是一个非常好的例子,但不幸的是它没有帮助我找出我的代码有什么问题。

    希望有人可以帮助我。

2 个答案:

答案 0 :(得分:4)

看看这两个项目,其中包括您要创建的效果:

https://github.com/blommegard/SBTickerView

https://github.com/raweng/FlipView

答案 1 :(得分:1)

应该是

CALayer *lay_closingImageHalf = [CALayer layer];
CALayer *lay_fixedImageHalf = [CALayer layer];

而不是

CALayer *lay_closingImageHalf;
CALayer *lay_fixedImageHalf;

至少。

您还需要设置lay_closingImageHalflay_fixedImageHalf

的帧
[lay_closingImageHalf setFrame:rect_closingImageHalf];
[lay_fixedImageHalf setFrame:rect_fixedImageHalf];

并且它的翻转动画仍然没有折叠...你确定它是你的代码吗?