首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

iOS present一个viewController后动画失效的问题(3)

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的消息发送机制后应当会理解,这里就不多说了。
返回列表