我有一个View
显示和隐藏给用户一些提示。
显示和隐藏方法看起来像这样:
-(void)show{
[UIView animateWithDuration:3.0f
animations:^{
//do something to show self to give hint;
self.frame = CGRectMake(0,0,0,0);
} completion:nil];
}
-(void)hide{
[UIView animateWithDuration:3.0f
animations:^{
//do something to hide self to give hint;
self.frame = CGRectMake(centerX,centerY,100,100);
} completion:nil];
}
当显示新 View 时,我必须调用hide method
,然后 show method
。但持续时间延迟3.0f会导致一些错误。我正在使用这样的方法:
dispatch_async(dispatch_get_main_queue(), ^{
[view hide];
});
dispatch_async(dispatch_get_main_queue(), ^{
[view show];
});
我正在打电话show method
就在hide method
之后。动画无法按照提交到队列的顺序执行。我想要的是show method
恰好在 hide method
之后执行完全的。如何控制这两个方法的顺序。
我认为我无法使用完成处理程序,因为我无法确定在何处调用这两个方法,或者当我调用另一个 show method
时是否显示 View 或hide method
.
如果我不清楚,有什么建议吗?我将重新编辑我的问题。
PS:
这不仅仅是一闪而过。下次什么时候show
方法被调用时,我无法保证最后一个 View 被显示或隐藏以及最后一个 View 显示多长时间,也就是说,如果正在显示 View 并且 hide
方法已经被调用并且已经完成,那么show
调用方法,结果是正确的。如果正在显示 View ,则需要呈现另一个提示 View ,我将调用 hide
首先,然后show
,自 main_queue
是串行的,但动画 block 是同步执行的,所以结果是错误的。我正在寻找 GCD 中是否有某种锁可以帮助我在最后一个排队 block 完成后执行一个 block ,而不是在 show
内更改和hide
方法。因为有许多其他电话到 show
和hide
方法具有许多不同类型的参数,我需要修复代码中的许多地方。
最佳答案
如果您想按照任务添加到队列的顺序一次执行一个任务,请使用串行队列。
因此,您可以使用串行队列按添加的顺序一次执行显示和隐藏任务。是的,主队列就可以了。
然而 UIView -animateWithDuration:animations: 方法是一种异步调用,该方法立即返回。所以你需要等到完成 block 被调用。
如果您想等到某些任务完成,请使用调度组。但你应该避免像这样在主队列上等待。它阻塞了主队列。糟糕的应用程序。
因此,您可能需要使用串行队列和调度组,如下所示。
属性和初始化
@property (nonatomic, strong) dispatch_queue_t serialQueue;
@property (nonatomic, strong) dispatch_group_t group;
-(void)initQueue {
// create a serial queue
self.serialQueue = dispatch_queue_create("com.example.serialQueue", 0);
// create a dispatch group
self.group = dispatch_group_create();
}
使用串行队列和调度组的方法
-(void)animateSyncWithDuration:(NSTimeInterval)duration animations:(block_t)animations {
dispatch_async(self.serialQueue, ^{
/*
* This block is invoked on the serial queue
* This block would never be executed concurrently
*/
/*
* Enter the dispatch group
*/
dispatch_group_enter(self.group);
dispatch_async(dispatch_get_main_queue(), ^{
/*
* This block is invoked on the main queue
* It is safe to use UIKit
*/
[UIView animateWithDuration:duration animations:animations completion:^{
/*
* This completion block is invoked on the main queue
* Now leave the dispatch group
*/
dispatch_group_leave(self.group);
}];
});
/*
* Wait until leaving the dispatch group from the UIView animation completion block
* It means it blocks the serial queue
*/
dispatch_group_wait(self.group, DISPATCH_TIME_FOREVER);
});
}
显示和隐藏
-(void)show{
[self animateSyncWithDuration:3.0f animations:^{
//do something to show self to give hint;
self.frame = CGRectMake(0,0,0,0);
}];
}
-(void)hide{
[self animateSyncWithDuration:3.0f animations:^{
//do something to hide self to give hint;
self.frame = CGRectMake(centerX,centerY,100,100);
}];
}
关于ios - 如何使用GCD控制动画序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27601758/