Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/101.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 如何在CABASICanization后使UI对象具有响应性_Ios_Objective C_Core Animation_Cabasicanimation - Fatal编程技术网

Ios 如何在CABASICanization后使UI对象具有响应性

Ios 如何在CABASICanization后使UI对象具有响应性,ios,objective-c,core-animation,cabasicanimation,Ios,Objective C,Core Animation,Cabasicanimation,我在试图找到一种方法使我的UI对象(UISegmentedControl)在CABasicAnimation滑入并反弹后具有触摸响应时遇到困难。我怎样才能做到这一点 我知道UI对象在移动后位于表示树中。但是我真的很喜欢Cabasicanization提供的setTimingFunction功能,我只是无法使用UIView动画获得如此平滑的反弹 动画GIF示例(循环): 我在viewDidLoad内部使用的代码 CABasicAnimation *startAnimation = [CABasi

我在试图找到一种方法使我的UI对象(UISegmentedControl)在CABasicAnimation滑入并反弹后具有触摸响应时遇到困难。我怎样才能做到这一点

我知道UI对象在移动后位于表示树中。但是我真的很喜欢Cabasicanization提供的setTimingFunction功能,我只是无法使用UIView动画获得如此平滑的反弹

动画GIF示例(循环):

我在viewDidLoad内部使用的代码

CABasicAnimation *startAnimation = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
[startAnimation setFromValue:[NSNumber numberWithFloat:0]];
[startAnimation setToValue:[NSNumber numberWithFloat:slidingUpValue]];
[startAnimation setDuration:1.0];
startAnimation.fillMode = kCAFillModeForwards;
startAnimation.removedOnCompletion = NO;
[startAnimation setTimingFunction:[CAMediaTimingFunction functionWithControlPoints:0.0 :0.0 :0.3 :1.8]];
[[gameTypeControl layer] addAnimation:startAnimation forKey:nil];
出了什么问题 问题在于这两行代码,并且不理解使用它们的副作用:

startAnimation.fillMode = kCAFillModeForwards;
startAnimation.removedOnCompletion = NO;
第一行将动画配置为在动画完成后继续显示结束值(您可以在中看到fillMode和其他计时相关属性的可视化)

第二行配置动画,使其在完成后保持附着到层

一开始听起来不错,但缺少了核心动画的一个重要部分:添加到层的动画不会影响模型,只会影响演示。在“”一节的第二页提到这一点:

图层对象的数据和状态信息与该图层内容在屏幕上的视觉表示分离

动画发生在一个单独的层上,称为演示层,这是您在屏幕上看到的。如果在动画期间打印动画特性的值,则这些值根本不会更改

在动画过程中,演示文稿和模型之间存在差异,但动画可能很短,并且这种差异会在动画完成后立即消失,因此这并不重要。。。除非动画没有消失。然后差异一直存在,现在您必须处理两个位置的不同步数据

如何不解决这个问题 可以说一切看起来都很好,只是命中测试是错误的。让我们进行补丁命中测试!更改命中测试以使用段控件层的表示层,命中测试将正常工作。很好,对吗?这就像是把一块石膏贴在另一块上面,而不是从源头上解决问题

如何消除副作用 其实很简单:不要使用这些线条,在动画完成后删除它们。有人可能会说,苹果在幻灯片和示例代码中使用了这种技术(不删除动画),所以这是苹果的建议,但有一个微妙的细节很容易被忽略:

当苹果在WWDC 2007上推出核心动画时,他们使用这种技术来制作被移除的层的动画(例如,淡出)。以下引用自第211课时-向应用程序添加核心动画:

  • 要设置层移除的动画,请将动画与
    fillMode=forwards,removedOnCompletion=NO
    • 动画代理可以删除该层
在这种情况下,完全可以不删除动画,因为它可能会导致层在从层层次中删除之前跳回其原始大小、不透明度等一帧。正如他们在上面的幻灯片中所说:“动画代理可以删除层”(即:执行清理)

在其他情况下,没有人进行清理,您将在两个位置上留下不同步的数据(如上所述)

解决方案是动画的另一种方法 在制作动画时,我尝试这样想:

如果动画神秘消失,则模型值应为预期的结束状态

应用到您的示例中,分段控件正在向其最终位置移动,以停止并保持在那里。在这种情况下,分段控件的实际位置应为结束位置。即使没有动画,应用程序也应该可以工作

那么动画呢?不是从0偏移设置动画到某个偏移,而是反转该偏移并从某个负偏移设置动画到0偏移

CABasicAnimation *startAnimation = [CABasicAnimation animationWithKeyPath:@"transform.translation.y"];
[startAnimation setFromValue:@(-slidingUpValue)]]; // these two changed 
[startAnimation setToValue:@(0.0)];                // places with each other
[startAnimation setDuration:1.0];
// no fill mode
// animation is removed on completion
[startAnimation setTimingFunction:[CAMediaTimingFunction functionWithControlPoints:0.0 :0.0 :0.3 :1.8]];
[[gameTypeControl layer] addAnimation:startAnimation forKey:@"Move in game type control from bottom"]; // I like adding descriptive keys for easier debugging

谢谢你的代码风格修复Mani。看起来好多了。这个效果很好!谢谢你花这么多时间回答我的问题。这些信息帮助我更多地了解了这个惊人的主题(CA),并缩短了我的代码。我也很高兴我不需要使用UIView动画来尝试和复制setTimingFunction这样的效果。你刚刚让我过了一周!回答得很好,大卫!(+1)您是SO社区的资产。