Swift 为什么延迟的动画不与for循环同步?

Swift 为什么延迟的动画不与for循环同步?,swift,multithreading,Swift,Multithreading,我有一个数组的元素,我想动画。我在索引中为每个增量添加一个延迟。但是,某些元素同时设置动画(通常一次两个) 我不确定这是因为for循环没有以恒定的速度迭代,还是主线程对它的调用太多 *注意-flipCard不是问题所在。如果我只是将cell.alpha设置为0,问题仍然存在 有问题的Gif-- 不能将UIView.animate()与完成处理程序一起使用吗?这样,当第一个动画完成时,您可以直接切换下一个动画。我决定不关心GCD或for循环时间,而是使用计时器。它工作得很好 private fu

我有一个数组的元素,我想动画。我在索引中为每个增量添加一个延迟。但是,某些元素同时设置动画(通常一次两个)

我不确定这是因为for循环没有以恒定的速度迭代,还是主线程对它的调用太多

*注意-flipCard不是问题所在。如果我只是将cell.alpha设置为0,问题仍然存在

有问题的Gif--


不能将UIView.animate()与完成处理程序一起使用吗?这样,当第一个动画完成时,您可以直接切换下一个动画。

我决定不关心GCD或for循环时间,而是使用计时器。它工作得很好

private func animateCells() {
    var cells: [CardCell] = []
    for section in 0 ..< collectionView.numberOfSections {
        for row in 0 ..< collectionView.numberOfItems(inSection: section) {
            guard let cell = collectionView.cellForItem(at: IndexPath(row: row, section: section)) as? CardCell else { continue }
            cells.append(cell)
        }
    }
    var animationIndex = 0
    Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { (timer) in
        cells[animationIndex].flipCard()
        animationIndex += 1
        if animationIndex ==  cells.count {
            UIView.animate(withDuration: 0.5, animations: {
                self.playButton.alpha = 1
            })
            timer.invalidate()
        }
    }.fire()
}
private func animateCells(){
变量单元格:[CardCell]=[]
对于0..
DispatchQueue.main是一个串行队列,可确保任务按照添加到队列中的顺序执行。然而,dispatch_async在添加到队列之后返回,并且可能尚未完成,其余代码(for循环)开始执行

发生的情况是,“for”循环将多个代码块(任务)放入主队列,这些代码块将按顺序执行,但执行时间可能取决于处理器的可用性。某些任务可能比其他任务更快地得到日程安排。调度程序在运行时调度任务,无法预测。这就是为什么你看到它没有按固定的间隔执行

你可以试试类似的东西

Timer.scheduledTimer(withTimeInterval: delayNextFlipMiliSeconds, repeats: false) { (timer) in
         DispatchQueue.main.sync {
                //Your Code
            }
    }.fire()

使用DispatchQueue.main.sync将确保先执行“您的代码”,然后再转到代码的其余部分。但是,使用Debug Cuffel.Ma..Syc也会降低用户的UI,但我认为这是可以忽略的。

你是否尝试使用<代码>动画?持续时间:延迟:选项:动画:完成:< /代码>具有延迟值而不是使用GCD?我想在上一次的中间启动下一个动画,完成后就不需要了。感谢您解释主队列如何处理执行顺序。但是,如果我们使用计时器,我认为根本不需要使用DispatchQueue.main?
private func animateCells() {
    var cells: [CardCell] = []
    for section in 0 ..< collectionView.numberOfSections {
        for row in 0 ..< collectionView.numberOfItems(inSection: section) {
            guard let cell = collectionView.cellForItem(at: IndexPath(row: row, section: section)) as? CardCell else { continue }
            cells.append(cell)
        }
    }
    var animationIndex = 0
    Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { (timer) in
        cells[animationIndex].flipCard()
        animationIndex += 1
        if animationIndex ==  cells.count {
            UIView.animate(withDuration: 0.5, animations: {
                self.playButton.alpha = 1
            })
            timer.invalidate()
        }
    }.fire()
}
Timer.scheduledTimer(withTimeInterval: delayNextFlipMiliSeconds, repeats: false) { (timer) in
         DispatchQueue.main.sync {
                //Your Code
            }
    }.fire()