Consider the following: I created a reusable subclass of UIView that has a background and some content placed in its subzones. As a responsible developer, I aligned the views in the view based on its safe area so that it automatically pastes its contents when necessary (for example, on the iPhone X):

Fine! The internal view goes from edge to edge when it is inside the safe zone, and inserts its contents from below when it is hung out of the safe zone.
Now let's say that initially the view should be off-screen, but when the user deletes something in my application, I want my view to come to life in the center of the screen and it should be animated at the second touch. Let it be implemented like this:
@implementation ViewController {
UIView* _view;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(animate:)]];
}
- (void)animate:(UITapGestureRecognizer*)sender {
if (_view == nil) {
_view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
_view.backgroundColor = UIColor.redColor;
UIView* innerView = [[UIView alloc] initWithFrame:CGRectMake(5, 5, 90, 90)];
innerView.translatesAutoresizingMaskIntoConstraints = NO;
innerView.backgroundColor = UIColor.blueColor;
[_view addSubview:innerView];
[_view addConstraints:@[[_view.safeAreaLayoutGuide.topAnchor constraintEqualToAnchor:innerView.topAnchor constant:-5],
[_view.safeAreaLayoutGuide.rightAnchor constraintEqualToAnchor:innerView.rightAnchor constant:5],
[_view.safeAreaLayoutGuide.bottomAnchor constraintEqualToAnchor:innerView.bottomAnchor constant:5],
[_view.safeAreaLayoutGuide.leftAnchor constraintEqualToAnchor:innerView.leftAnchor constant:-5]]];
_view.center = CGPointMake(self.view.bounds.size.width / 2,
self.view.bounds.size.height + _view.bounds.size.height / 2);
[self.view addSubview:_view];
[UIView animateWithDuration:1 animations:^{
_view.center = CGPointMake(self.view.bounds.size.width / 2,
self.view.bounds.size.height / 2);
}];
} else {
[UIView animateWithDuration:1 animations:^{
_view.center = CGPointMake(self.view.bounds.size.width / 2,
self.view.bounds.size.height + _view.bounds.size.height / 2);
} completion:^(BOOL finished) {
[_view removeFromSuperview];
_view = nil;
}];
}
}
@end
, , , :

. , , :

, , , , .
, [self.view layoutIfNeeded]
, , - ,

. , , , 5- .
shouldAlignContentToSafeArea
shouldAlignContentToBounds
?
, , ...