【问题标题】:Animate UIView to fold one half onto the other half动画 UIView 将一半折​​叠到另一半
【发布时间】:2012-01-21 06:12:12
【问题描述】:

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

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

  1. 创建 UIView 的渲染图像
  2. 根据我要折叠到另一半的一半来拆分它
  3. 将渲染图像的相应一半添加到相应的图层中
  4. 将这两个图层添加到具有白色背景且没有内容的背景图层中(它只是用来制作白色背景以覆盖视图的原始图层)
  5. 将背景层添加到视图层
  6. 设置折叠层的变换
  7. 开始动画

应该有效,但无效!我不知道为什么。 :(

这里是方法的源代码:

-(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,这是一个非常适合此任务的示例,但不幸的是它并没有帮助我找出我的代码有什么问题。

希望有人可以帮助我。

【问题讨论】:

  • 不工作意味着“什么都不画”或“动画不正确”或“崩溃”或???
  • 不起作用意味着在这种情况下,Backgroundlayer 似乎是不可见的(因此也使子层不可见,至少我看不到它们)。因此,如果要动画的图层不可见,我将看不到动画。为什么它是隐形的,虽然我不知道。但是您应该能够在任何项目中测试此方法:上次我通过将视图层添加到动画中来测试它。这至少产生了一个可见的动画,虽然它当然不是我们想要的。
  • 没人知道吗?也许我应该在这个上开始赏金。 ://

标签: objective-c ios ipad calayer caanimation


【解决方案1】:

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

https://github.com/blommegard/SBTickerView

https://github.com/raweng/FlipView

【讨论】:

  • FlipView 使用我已经尝试过的 AFKPageFlipper。不过,我会研究 SBTickerView,因为从我想要的功能来看,它看起来很有希望。它比 AFKPageFlipper 更接近我的需要。
  • 谢谢。 SBTickerView 正是我所需要的。它缺少 AFKPageFlipper 的功能,但是可以很容易地集成。 SBTickerView 也更容易集成。所以你已经赢得了赏金。 :)
  • 很高兴听到您找到了解决方案 :) 作为附加提示 - 在寻找这些东西时,请务必查看 cocoacontrols.com 和 github.com - 那里有很多有用的开源项目,但其中很多都不容易通过 Google 找到。
  • 再次感谢。我经常检查 github 上的新东西,但我一定错过了这个 sbTickerView。 :)
【解决方案2】:

应该是

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

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

【讨论】:

  • 它的部分代码来自我的代码,部分代码来自 github 上的 afkpageflipper 项目。但我想要的效果本身并不是翻转,而是当你合上一本打开的书时,将一层的一半折叠到另一层上。至于你的cmets,它们都是正确的。我不知道我怎么能忽略这一点。我会修复它并给出回应。 :)
  • 好的,现在它至少可以制作动画了。不是我想要的,但至少我可以更深入地挖掘它。谢谢!如果我知道更多,我会告诉你。
  • 顺便说一句,您认为翻转和折叠有什么区别?我一直认为翻转是整个视图的完整翻转,折叠是视图中间的折叠,折叠完成后一半覆盖另一半。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多