views:

66

answers:

1

In my iPhone app I have a UIScrollView with custom content views. At some points, a custom popup view is dynamically added to the content with a zoom animation on appear and disappear. I'm using block-based animations with a completion handler that calls [self removeFromSuperView] as follows:

- (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];
                     }];
}

Mostly this works, but now and again following this animation the UI completely locks up and is unresponsive to any touch. I'm pretty sure this animation the source of the problem as with the animation code commented out I haven't been able to reproduce it. Breaking in with the debugger, all three threads appear to be idle:

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

Instruments shows that my app is taking no CPU time, so it's some kind of deadlock. Can anyone shed any light on this behaviour, and how to avoid it?

Update: I've done some more digging and using the traditional animation API the bug also seems to have disappeared. Could this be a bug in the new animation framework?

- (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];
}
A: 

Not sure if this is of any help, but I have seen a lot of erratic behavior anytime animation (or anything with the ui for that matter is called from a thread other than the main thread).. to ensure this, i call my animation function like this

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

Yes, you have to do all UI operations on the main thread. The -dismissPopup method above is called on the main thread.
Neil Gall