iOS present一个viewController后动画失效的问题(3)
- UID
- 1066743
|
iOS present一个viewController后动画失效的问题(3)
我就有点好奇,他是用什么方法移除所有的动画的,不会是用layer的removeAllAnimations方法吧?虽然自己都不相信苹果会用会用这个方法,但是好奇心太强,想试试,我想到两个试的办法:
一、写一个Layer继承自CALayer,然后把相关layer都换成这个类的。
二、Method Swizzling,利用runtime交换removeAllAnimations的实现。
自然而然地,我采用了第二个方法,因为它有逼格啊 O(∩_∩)O
为了保证一开始方法就被替换,我在appDelegate中加入了如下代码:
AppDelegate.m
- (void)exchangeMethod {
Method original = class_getInstanceMethod([CALayer class], @selector(removeAllAnimations));
Method custom = class_getInstanceMethod([AppDelegate class], @selector(customMethod));
method_exchangeImplementations(original, custom);
}
- (void)customMethod {
NSLog(@"%s开始",__func__);
NSLog(@"self=%@",self);
NSLog(@"%s结束",__func__);
}
- (BOOL)applicationUIApplication *)application didFinishLaunchingWithOptionsNSDictionary *)launchOptions {
// Override point for customization after application launch.
[self exchangeMethod];
return YES;
}
经过以上代码,我期待,在present的时候会打印出出我想要的东西,事实就是并没有打印,既然一开始就料到了苹果不会采用这么“低端”的方法来移除动画,所以也没什么好伤心的。写都写了,不如试试切换后台呢?
我把Present 到的那个viewController做了下如修改(经过一段延迟之后再加动画),使动画能够运行:
//关键代码
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
v = [[UIView alloc] initWithFrame:CGRectMake(0, 20, 100, 100)];
v.backgroundColor = [UIColor orangeColor];
[self.view addSubview:v];
CABasicAnimation *ani = [CABasicAnimation animationWithKeyPath"transform.rotation.z"];
ani.fromValue = @0;
ani.delegate = self;
ani.toValue = @M_PI;
ani.duration = 2.0;
ani.repeatCount = HUGE_VALF;
[v.layer addAnimation:ani forKey"opm"];
});
等待动画执行后,我把app切换到后台,控制台输出:
del07-10[9174:251348] -[AppDelegate customMethod]开始
del07-10[9174:251348] self=<CALayer: 0x600000031280>
del07-10[9174:251348] -[AppDelegate customMethod]结束
很令人激动啊,居然执行了,也就是说调用了removeAllAnimations方法,如果有童鞋不理解为什么这里输出的self是CALayer而不是Appdelegate,那么你们理解runtime的消息发送机制后应当会理解,这里就不多说了。 |
|
|
|
|
|