【问题标题】:Is there a way to disable all animations on ios?有没有办法禁用ios上的所有动画?
【发布时间】:2014-09-04 15:03:59
【问题描述】:

仍应调用回调。我想用它来进行 KIF 测试。目的是减少测试时间。

【问题讨论】:

  • 不完全是您正在寻找的,但 UIView setAnimationsEnabled: 上的类方法是一种让所有动画在没有实际动画的情况下生效的便捷方法。
  • 你试过调配animateWithDuration: 吗?
  • 没有,你能解释一下吗?
  • setAnimationsEnabled: 只影响 UIKit 动画,不影响核心动画。
  • 如何调配 -[CALayer addAnimation:forKey:] 什么都不做?

标签: ios kif


【解决方案1】:

修饰@Leo的回答:

如果您不需要细粒度控制,在大多数情况下,设置应用程序的 keyWindow 的 speed 属性将加快所有动画的速度。所以你只需要:

[UIApplication sharedApplication].keyWindow.layer.speed = 5.0;

这可以在任何你想要的地方调用。我们在所有测试中都设置了它,这样动画总是很快的。 (如果您要使用 BDD 或任何您想要的结构,可以通过子类化或使用 beforeAll 来实现。)

此外,如果您有兴趣,我们发现从 speed = 1.0 到 speed = 5.0 时,速度平均提高了大约 10%,其中 5.0 实际上快到几乎可以瞬间完成。这显然会根据您的应用通过多少动画而有所不同,但考虑到启用它的容易程度,对于大多数测试来说,这很容易。

【讨论】:

  • 谢谢,这在 viewDidAppear 或更高版本中运行良好。任何更早的,它似乎被忽略或重置。
【解决方案2】:

更新:

我试过这个,它似乎工作。动画会“运行”,它们根本不需要时间......

static void (*__original_CALayerAddAnimationForKey)( CALayer *, SEL, CAAnimation *, NSString * ) ;
static void CALayerAddAnimationForKey( CALayer * self, SEL _cmd, CAAnimation * anim, NSString * key )
{
    anim.duration = 0.0 ;
    (*__original_CALayerAddAnimationForKey)( self, _cmd, anim, key ) ;
}

static id<CAAction> CALayerActionForKey( CALayer * self, SEL _cmd, NSString * key )
{
    return nil ;
}


int main(...)
{
    // head patch -[CALayer addAnimation:forKey:] to set all animation durations to 0.0
    __original_CALayerAddAnimationForKey = (void(*)(CALayer *, SEL, CAAnimation *, NSString*))class_getMethodImplementation( [ CALayer class ], @selector( addAnimation:forKey: ) ) ;
    assert( __original_CALayerAddAnimationForKey ) ;

    class_replaceMethod( [ CALayer class ], @selector( addAnimation:forKey: ), (IMP)CALayerAddAnimationForKey, "v@:@@" ) ;

    // replace -[CALayer actionForKey:] with a function that always returns nil (no action)
    class_replaceMethod( [ CALayer class ], @selector( actionForKey: ), (IMP)CALayerActionForKey, "@@:@" ) ;

    ...

}

这会将传递给 -addAnimation:forKey: 的每个动画的持续时间更改为 0.0,并且对于所有对 -actionForKey: 的调用也返回 nil em>

您实际上不能只删除动画——它们可能具有与完成相关的副作用和操作。


进一步了解@michaels 的建议:

你可以尝试调配 -CALayer addAnimation:forKey: 什么都不做。 (也许还有 -CALayer actionForKey: 来返回 null。)

#import <objc/runtime.h>

static void CALayerAddAnimationForKey( CALayer * self, SEL _cmd, NSString * key ) { }

...

class_replaceMethod( [ CALayer class ], 
    @selector( addAnimation:forKey: ), 
    (IMP)CALayerAddAnimationForKey, 
    "v@:@@" ) ;

【讨论】:

    【解决方案3】:

    最简单的方法是将窗口层的speed 属性设置为大数字。它的作用是控制动画的速度; >1 的值会增加速度。设置一个足够高的值,动画将花费比帧长度(1/60 秒)更短的时间。

    这是最好的选择,因为它同时影响 UIKit 和 Core Animation 动画。从iOS7开始,很多系统动画其实都是直接用Core Animation来实现的。

    【讨论】:

      猜你喜欢
      • 2019-08-29
      • 1970-01-01
      • 2019-08-20
      • 2015-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      相关资源
      最近更新 更多