As simple as it might be, I still find my self struggling with the correct solution.
I'm trying to understand what is the correct way to find the REAL UIView
(or any other subview) frame inside viewDidLoad
when using Auto Layout.
The main issue is that in viewDidLoad, the views aren't applied their constraints. I know that the "known" answer for this situation is
override func viewDidLoad() {
super.viewDidLoad()
view.layoutIfNeeded()
stepContainer.layoutIfNeeded() // We need this Subview real frame!
let realFrame = stepContainer.frame
}
But I found out that it's not ALWAYS working, and from time to time it give's wrong frame (ie not the final frame that is displayed).
After some more researching I found that warping this code under DispatchQueue.main.async { }
gives accurate result. But I'm not sure if it's the correct way to handle that, or am I causing some kind of under-the-hood issues using this. Final "working" code:
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
self. stepContainer.layoutIfNeeded()
print(self. stepContainer.frame) // Real frame..
}
}
NOTE : I need to find what is the real frame only from viewDidLoad, please don't suggest to use viewDidAppear/layoutSubviews etc.
viewWillAppear
andviewDidLayoutSubviews
has run. The timing has changed, but in a less robust way than it would be to put the same code in either of those methods (because it relies on timing - that wouldn't be true if the view was loaded but not added as a sub view) – Sword