Reputation: 1508
Sometimes when the autolayout or the UI changes are not getting performed as I want I wrap the code into a DispatchQueue.main.async
and it gets solved (e.g):
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransition(to: size, with: coordinator)
DispatchQueue.main.async {
self.tableview.reloadData()
}
}
But debugging this code with (Thread.current
) without the DispatchQueue
it tells me that is already in the main thread but it doesn’t do the animation well, and just adding the DispatchQueue.main.async
works fine. I would like to know what does exactly DispatchQueue.main.async
to make that it works. Because I thought it just made that the code gets executed in the main thread, but if it is already executing in main thread it shouldn’t do anything… But with this it works fine and without is creating layout issues.
(It has happened to me with different pieces of code and different apps, and I have always debugged and tells me that is already in the Main thread).
I thought it could be because a bit delay generated by dispatchQueue, but it has happened to me in more places where a delay is not needed (Swift Animate duration not working in CGAffineTransform -> Today I have debugged this issue without the dispatchMainQueue and it is getting executed in main thread as well but it is not working without the dispatch)
Upvotes: 0
Views: 700
Reputation: 12144
Simply, when you use DispatchQueue.main.async
, self.tableview.reloadData()
will be called after a small delay (because block will be executed in the next loop). That's why you have difference.
In this case, viewWillTransition(to:with:)
is executed when device will be rotated. It means that something maybe wrong at this time and device hasn't rotated yet. So if you call self.tableview.reloadData()
, it will may give a wrong result.
Why DispatchQueue.main.async
resolves the problem? - It's because DispatchQueue.main.async
give a delay before block is executed and with this delay, self.tableview.reloadData()
will be called after device is finish rotating . That's why it gives right result
Do it with animate(alongsideTransition:completion:)
and you won't need to use DispatchQueue.main.async
override func willTransition(to newCollection: UITraitCollection, with coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animate(alongsideTransition: nil, completion: { (_) in
self.tableview.beginUpdates()
self.tableview.endUpdates()
})
}
Upvotes: 3