通过动画删除UIScrollView子视图来冻结UI

时间:2010-09-29 15:33:18

标签: iphone cocoa-touch uiview uikit ios4

在我的iPhone应用程序中,我有一个带有自定义内容视图的UIScrollView。在某些点上,自定义弹出视图会动态添加到内容中,并且会显示和消失缩放动画。我正在使用基于块的动画和一个调用[self removeFromSuperView]的完成处理程序,如下所示:

- (void)dismissPopup {
    CGRect rect = self.frame;
    rect.origin.y += rect.size.height/2 * (pointingDown ? 1 : -1);
    [UIView animateWithDuration:kZoomDuration
                     animations:^{
                         self.frame = rect;
                         self.transform = CGAffineTransformMakeScale(0.01, 0.01);
                     }
                     completion:^(BOOL finished) {
                         [self removeFromSuperview];
                     }];
}

大多数情况下这都有效,但是现在又一次跟随这个动画,UI完全锁定并且对任何触摸都没有响应。我很确定这个动画是问题的根源,就像动画代码注释掉我无法再现它。打破调试器,所有三个线程似乎都处于空闲状态:

Thread-1
#0  0x32fd1c98 in mach_msg_trap
#1  0x32fd3d6a in mach_msg
#2  0x34432c3e in __CFRunLoopServiceMachPort
#3  0x344324c8 in __CFRunLoopRun
#4  0x34432276 in CFRunLoopRunSpecific
#5  0x3443217e in CFRunLoopRunInMode
#6  0x3026b5f2 in GSEventRunModal
#7  0x3026b69e in GSEventRun
#8  0x31ad0122 in -[UIApplication _run]
#9  0x31ace12e in UIApplicationMain
#10 0x00002b06 in main at main.m:14

Thread-2
#0  0x32ffe330 in kevent
#1  0x330a7b74 in _dispatch_mgr_invoke
#2  0x330a75c4 in _dispatch_queue_invoke
#3  0x330a7764 in _dispatch_worker_thread2
#4  0x3304b680 in _pthread_wqthread

Thread-3
#0  0x32fd1c98 in mach_msg_trap
#1  0x32fd3d6a in mach_msg
#2  0x34432c3e in __CFRunLoopServiceMachPort
#3  0x344324c8 in __CFRunLoopRun
#4  0x34432276 in CFRunLoopRunSpecific
#5  0x3443217e in CFRunLoopRunInMode
#6  0x34b524e8 in RunWebThread
#7  0x3304b284 in _pthread_start

仪器显示我的应用程序没有占用CPU时间,因此它存在某种僵局。任何人都可以对这种行为有所了解,以及如何避免它?

更新:我已经做了一些挖掘并使用传统的动画API,这个bug似乎也已经消失了。这可能是新动画框架中的错误吗?

- (void)dismissPopup {
    CGRect rect = self.frame;
    rect.origin.y += rect.size.height/2 * (pointingDown ? 1 : -1);
    [UIView beginAnimations:@"dismissPopup" context:nil];
    [UIView setAnimationDuration:kZoomDuration];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationDidStopSelector:@selector(animationDidStop:finished:context:)];
    self.frame = rect;
    self.transform = CGAffineTransformMakeScale(0.01, 0.01);
    [UIView commitAnimations];
}

- (void)animationDidStop:(NSString *)animationID finished:(NSNumber *)finished context:(void *)context {
    [self removeFromSuperview];
}

2 个答案:

答案 0 :(得分:2)

您可能应该为动画尝试此方法: +animateWithDuration:delay:options:animations:completion:

带有选项:UIViewAnimationOptionAllowUserInteraction

答案 1 :(得分:0)

不确定这是否有任何帮助,但我已经看到很多不稳定的行为随时动画(或者任何有关于该问题的ui从主线程以外的线程调用)..为了确保这一点,我像这样调用我的动画功能

[self performSelectorOnMainThread:@selector(animationFunctionGoesHere)withObject:nil waitUntilDone:YES];