Everything turned out to be quite simple.
The order of the UIViewController life cycle method calls is as follows:
- viewDidLoad
- viewWillAppear
- viewWillLayoutSubviews
- viewDidLayoutSubviews
- viewDidAppear
Moreover, when we call viewWillLayoutSubviews, we still do not have real frame coordinates / sizes, considering constraints, and in viewDidLayoutSubviews we already have real coordinates, and we can easily change them there.
If we change the coordinates / sizes in viewDidAppear, where we already have real coordinates / sizes, then on the screen with a lot of elements we will see the "jumping" of elements.
Therefore, the coordinates should be changed in viewDidLayoutSubviews, since in this place we can already get the real coordinates / sizes of the surrounding elements, but the elements have not yet been displayed to the user. viewDidLayoutSubviews should be used when the coordinates / dimensions of an element depend on the coordinates or sizes of other elements and these dimensions are difficult to calculate in advance.