草庐IT

objective-c - 动画 UIView 将一半折​​叠到另一半

coder 2024-01-11 原文

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

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

  1. 创建 UIView 的渲染图像
  2. 根据我想将哪一半折叠到另一半上来拆分它
  3. 将渲染图像的相应一半添加到相应层
  4. 将这两个层添加到具有白色背景且没有内容的背景层(它只是用来制作白色背景以覆盖 View 的原始层)
  5. 将背景层添加到 View 层
  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对于这项任务来说,这是一个非常好的例子,但不幸的是,它并没有帮助我找出我的代码有什么问题。

希望有人能帮助我。

最佳答案

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

https://github.com/blommegard/SBTickerView

https://github.com/raweng/FlipView

关于objective-c - 动画 UIView 将一半折​​叠到另一半,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8521946/

有关objective-c - 动画 UIView 将一半折​​叠到另一半的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  3. ruby - 主要 :Object when running build from sublime 的未定义方法 `require_relative' - 2

    我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby​​1.9+ 关于ruby-主要:Objectwhenrun

  4. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  5. ruby-on-rails - Rails - 从另一个模型中创建一个模型的实例 - 2

    我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案

  6. ruby - 一个 YAML 对象可以引用另一个吗? - 2

    我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的ruby​​yaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir

  7. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

    Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

  8. ruby - 将一个超薄文件包含在另一个超薄文件中 - 2

    我在一个静态网站上工作(因此没有真正的服务器支持),我想在另一个网站中包含一个小的细长片段,可能会向它传递一个变量。这可能吗?在rails中很容易,虽然是render方法,但我不知道如何在slim上做(显然load方法不适用于slim)。 最佳答案 Slim包含Include插件,允许在编译时直接在模板文件中包含其他文件:require'slim/include'includepartial_name文档可在此处获得:https://github.com/slim-template/slim/blob/master/doc/incl

  9. objective-c - 在设置 Cocoa Pods 和安装 Ruby 更新时出错 - 2

    我正在尝试为我的iOS应用程序设置cocoapods但是当我执行命令时:sudogemupdate--system我收到错误消息:当前已安装最新版本。中止。当我进入cocoapods的下一步时:sudogeminstallcocoapods我在MacOS10.8.5上遇到错误:ERROR:Errorinstallingcocoapods:cocoapods-trunkrequiresRubyversion>=2.0.0.我在MacOS10.9.4上尝试了同样的操作,但出现错误:ERROR:Couldnotfindavalidgem'cocoapods'(>=0),hereiswhy:U

  10. ruby-on-rails - 如何使用 ruby​​ 从 self 方法调用另一个方法? - 2

    #app/models/product.rbclassProduct我从Controller调用方法1。当我运行程序时。我收到一个错误:method_missing(atlinemethod2(param2)).rbenv/versions/2.3.1/lib/ruby/gems/2.3.0/gems/activerecord-5.0.0/lib/active_record/relation/batches.rb:59:in`block(2levels)infind_each... 最佳答案 classProduct说明:第一个是类

随机推荐