在我的应用中,我需要检测ImagePicker
是否已准备好拍照。我在这里找到了一个解决方案:How to know if iPhone camera is ready to take picture?
所以我在viewDidLoad:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(showButton:)
name:AVCaptureSessionDidStartRunningNotification object:nil];
和选择器如下所示:
- (void)showButton:(NSNotification *)notification{
NSLog(@"---CAMERA READY");
[button setHidden:NO];
[button setAlpha:0.0];
[button setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 1.5, 1.5)];
[UIView animateWithDuration:.2 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
[button setAlpha:1.0];
[button setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0)];
} completion:^(BOOL finished) {
}];
NSLog(@"---CAMERA READY");
}
这里发生了一些奇怪的事情,因为两个NSLog都会立即出现,但整个按钮动画甚至会在30秒后触发。
UIView是否单独更新?如何同步日志和动画?
答案 0 :(得分:2)
将其放在答案框中以供将来的用户查看..
您遇到的情况会使您看起来未在主线程上调用通知,并且在后台线程上更新UI是未定义的行为。解决这个问题很简单,只需将方法的内容包装在dispatch_async()调用中,然后将所有内容发送回主队列。
- (void)showButton:(NSNotification *)notification {
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"---CAMERA READY");
[button setHidden:NO];
[button setAlpha:0.0];
[button setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 1.5, 1.5)];
[UIView animateWithDuration:.2 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{
[button setAlpha:1.0];
[button setTransform:CGAffineTransformScale(CGAffineTransformIdentity, 1.0, 1.0)];
} completion:nil];
NSLog(@"---CAMERA READY");
});
}
作为替代方法,您可以使用不同的NSNotificationCenter实例方法。具体来说,-addObserverForName:object:queue:usingBlock:
允许您指定应在哪个操作队列上执行回调块。在这种情况下,您需要传递[NSOperationQueue mainQueue];
。
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
self.localeChangeObserver = [center addObserverForName:NSCurrentLocaleDidChangeNotification object:nil
queue:mainQueue usingBlock:^(NSNotification *note) {
NSLog(@"The user's locale changed to: %@", [[NSLocale currentLocale] localeIdentifier]);
}];