No you still can't use viewDidLoad
for anything size/position related.
The first method that will have the actual "proper" dimensions is the viewDidLayoutSubviews
.
Regarding the phenomenon you are experiencing.
You are probably talking about the "root view" from your view controller.
As the apple docs say (bolding is mine):
A view controller’s root view is always sized to fit its assigned
space. For other views in your view hierarchy, use Interface Builder
to specify the Auto Layout constraints that govern how each view is
positioned and sized within its superview’s bounds. You can also
create constraints programmatically and add them to your views at
appropriate times. For more information about how to create
constraints, see Auto Layout Guide.
https://developer.apple.com/documentation/uikit/uiviewcontroller
This is why you are getting the correct width.
If you'd like to test, try adding a subview that fills the whole "root view" area. This one will probably just give you the dimensions that that are shown on the Interface Builder.
My test results:
Interface Builder -> "View as iPhone 7"
Simulator iPhone 5s:
Root View dimensions: (0.0, 0.0, 320.0, 568.0)
Sub View dimensions: (0.0, 0.0, 375.0, 667.0)
Simulator iPhone 7:
Root View dimensions: (0.0, 0.0, 375.0, 667.0)
Sub View dimensions: (0.0, 0.0, 375.0, 667.0)
Simulator iPhone 7 Plus:
Root View dimensions: (0.0, 0.0, 414.0, 736.0)
Sub View dimensions: (0.0, 0.0, 375.0, 667.0)
Interface Builder -> "View as iPhone 4s"
Simulator iPhone 5s:
Root View dimensions: (0.0, 0.0, 320.0, 568.0)
Sub View dimensions: (0.0, 0.0, 320.0, 480.0)
Simulator iPhone 7:
Root View dimensions: (0.0, 0.0, 375.0, 667.0)
Sub View dimensions: (0.0, 0.0, 320.0, 480.0)
Simulator iPhone 7 Plus:
Root View dimensions: (0.0, 0.0, 414.0, 736.0)
Sub View dimensions: (0.0, 0.0, 320.0, 480.0)
As you can see, the root view dimensions will always correspond to the device you are using as stated in the documents. While any other views will have the dimensions you can see on the interface builder.
This question will also help you understand how the life cycle works:
Why am I having to manually set my view's frame in viewDidLoad?