gpt4 book ai didi

ios - 如何使用GCD控制动画序列

转载 作者:塔克拉玛干 更新时间:2023-11-02 10:02:41 24 4
gpt4 key购买 nike

我有一个 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 时,我必须调用隐藏方法,然后调用显示方法。但是持续时间延迟 3.0f 会导致一些错误。我正在使用这样的方法:

dispatch_async(dispatch_get_main_queue(), ^{
[view hide];
});

dispatch_async(dispatch_get_main_queue(), ^{
[view show];
});

我在 hide 方法 之后立即调用了 show 方法。动画不能按照它们提交到队列的顺序执行。我想要的是在 hide 方法 完成之后执行的 show 方法。如何控制这两种方法的顺序。

我想我不能使用完成处理程序,因为我不能确定这两个方法在哪里被调用,或者当我调用另一个显示方法隐藏方法时是否显示 View >.

如果我不清楚,有什么建议吗?我会重新编辑我的问题。


附言:

这不仅仅是一闪而过。当调用下一个 show 方法时,我无法确保显示或隐藏最后一个 View 以及显示最后一个 View 多长时间,也就是说,如果正在显示 View 而 hide 方法已经被调用并且已经完成,然后调用 show 方法,结果是正确的。如果正在显示 View ,需要显示另一个提示 View ,我会先调用hide,然后调用show,因为main_queue是串行的但是动画 block 是同步执行的,所以结果是错误的。我正在寻找 GCD 中是否有某种锁可以帮助我在最后一个排队的 block 完成后执行一个 block ,而不是在 showhide 方法中进行更改。因为还有许多其他调用 showhide 方法的方法有很多不同种类的参数,我需要修复代码中的很多地方。

最佳答案

如果您想按照任务添加到队列的顺序一次执行一个任务,请使用串行队列。

因此您可以使用串行队列按添加顺序一次执行显示和隐藏任务。是的,主队列可以。

但是 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com