请考虑以下事项:我已经创建了一个可重用的UIView子类,它具有一个背景,并在其子视图中列出了一些内容。作为负责任的开发人员,我已根据其安全区域调整了视图的子视图,以便在必要时自动插入其内容(例如在iPhone X上):
出色!当内部视图在安全区域内时是边缘到边缘,并且当它从安全区域悬挂时将其内容从底部插入。
现在让我们说最初视图应该在屏幕外,但是当用户点击我的应用中的某个地方时,我希望我的视图动画显示在屏幕的中心,并且它应该在第二次点击。让我们像这样实现它:
@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]
来使效果不那么突然,但它并没有消除问题 - 底部空间将以动画方式增长而不是突然扩张:
这对我来说仍然是不可接受的。我希望它滑出来,就像它滑入一样,所有侧面都有5pt填充。
有没有办法在我的视图中添加shouldAlignContentToSafeArea
或shouldAlignContentToBounds
之类的标记来实现这一目标?
我只是想让它自动运行,但正确 ...
答案 0 :(得分:-1)
太简单的解决方案。试试这个并看(设置内部视图的中心等于动画视图中心 - innerView.center = animatingView.center;
)
@interface ViewController () {
UIView* animatingView;
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
[self setupAnimate];
}
- (void)setupAnimate {
[self.view addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(animate:)]];
}
- (void)animate:(UITapGestureRecognizer*)sender {
if (animatingView == nil) {
animatingView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
animatingView.backgroundColor = UIColor.redColor;
UIView* innerView = [[UIView alloc] initWithFrame:CGRectMake(5, 5, 90, 90)];
innerView.translatesAutoresizingMaskIntoConstraints = NO;
innerView.backgroundColor = UIColor.blueColor;
[animatingView addSubview:innerView];
innerView.center = animatingView.center;
animatingView.center = CGPointMake(self.view.bounds.size.width / 2,
self.view.bounds.size.height + animatingView.bounds.size.height / 2);
[self.view addSubview:animatingView];
[UIView animateWithDuration:1 animations:^{
animatingView.center = CGPointMake(self.view.bounds.size.width / 2,
self.view.bounds.size.height / 2);
}];
} else {
[UIView animateWithDuration:1 animations:^{
animatingView.center = CGPointMake(self.view.bounds.size.width / 2,
self.view.bounds.size.height + animatingView.bounds.size.height / 2);
} completion:^(BOOL finished) {
[animatingView removeFromSuperview];
animatingView = nil;
}];
}
}
结果如下: