我想在推入VC后立即更改集合视图的contentOffset.x。
所以我在viewWillAppear中调用了collectionView.setContentOffset(~)
。
但它没有工作,因为自动布局周期。
但是,如果我在DispatchQueue.main.async
块中调用collectionView.setContentOffset
,它就能工作!
代码如下:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
DispatchQueue.main.async {
collectionView.setContentOffset(
CGPoint(x: currentFolderIndex * collectionView.bounds.width), y: 0),
animated: false
)
}
}
当我打印布局方法的顺序时,我明白了为什么它会起作用。
在viewDidLayoutSubviews
之后调用DispatchQueue.main.async
块。
总是这样吗?
为什么会这样?
我好好奇啊!!
1条答案
按热度按时间lrl1mhuk1#
使用
async
基本上就是说“有时间的时候再做”。所以它将在未来不确定的时间完成(通常不会太久),并且可能在完成当前正在做的事情之后。并且调用函数在继续之前不会等待代码在主队列上执行。因此,在您的情况下,当调用
async
时,UI线程完成正在执行的操作,调用viewWillLayoutSubViews
,执行自动布局等,...当完成并有时间时,他异步执行setContentOffset
。然而,在理论上它并不能保证它永远是同一个顺序:UI线程可以在
viewDidAppear
之前找到时间,也可以在viewDidAppear
之前超额预定而没有时间......但实际上,我认为您可以安全地假设99.99%的时间都是相同的订单。注意:在其他情况下,您可以考虑使用
DispatchQueue.main.sync
,它会说“Do it ASAP and I 'm waiting for you”。但是,这可能是一个糟糕的想法,特别是如果您在UI线程中:您将在UI线程中等待UI线程执行其他操作,并且无法退出-这是一个死锁。更多详细信息here。