使用“自动布局”弹出键盘时,如何调整视图大小

我有一个视图(在这种情况下是UITableView ,但这并不重要)在我的UIViewController ,我希望在键盘弹出时调整高度。

在自动布局中执行此操作的最佳方法是什么? 目前在视图中我有这些约束:

  • 超级视图的顶层空间:0
  • 尾随空间到superview:0
  • 领先的超视空间:0
  • 底层空间到superview:0
  • 高度等于= 424

我认为最快的方法是删除高度和底部空间约束,并在调用keyboardDidAppear通知时调整代码中的实际视图,但还有其他方法吗?

编辑:我删除了高度限制,我的坏。

我会给你一个通用的想法,它可能需要根据你的实际项目进行重新调整。

swift 4.x

 let notificationTokenKeyboardWillAppear = NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillShow, object: nil, queue: nil) { (note) in guard let keyboardFrame = (note.userInfo?[UIKeyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue else { return } UIView.animate(withDuration: CATransaction.animationDuration(), animations: { tableView.contentInset = UIEdgeInsets(top: 0.0, left: 0.0, bottom: keyboardFrame.size.height, right: 0.0) }, completion: nil) } 

 let notificationTokenKeyboardWillHide = NotificationCenter.default.addObserver(forName: NSNotification.Name.UIKeyboardWillHide, object: nil, queue: nil) { (_) in UIView.animate(withDuration: CATransaction.animationDuration(), animations: { tableView.contentInset = .zero }, completion: nil) } 

注意:当您要释放视图并且不再需要基于闭包的观察者时,您需要通过调用removeObserver(_:)方法手动删除令牌


ObjC

我认为UITableView *_tableView已经在以前的某个地方正确设置了。

 - (void)viewDidLoad { // ... [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillShowNotification object:nil queue:nil usingBlock:^(NSNotification *note) { id _obj = [note.userInfo valueForKey:UIKeyboardFrameEndUserInfoKey]; CGRect _keyboardFrame = CGRectNull; if ([_obj respondsToSelector:@selector(getValue:)]) [_obj getValue:&_keyboardFrame]; [UIView animateWithDuration:0.25f delay:0.f options:UIViewAnimationOptionCurveEaseInOut animations:^{ [_tableView setContentInset:UIEdgeInsetsMake(0.f, 0.f, _keyboardFrame.size.height, 0.f)]; } completion:nil]; }]; [[NSNotificationCenter defaultCenter] addObserverForName:UIKeyboardWillHideNotification object:nil queue:nil usingBlock:^(NSNotification *note) { [UIView animateWithDuration:0.25f delay:0.f options:UIViewAnimationOptionCurveEaseInOut animations:^{ [_tableView setContentInset:UIEdgeInsetsZero]; } completion:nil]; }]; // ... 

}

注意:如果您的UITableView 不在屏幕的底部,则 应该在此行中细化 contentInset 值: [_tableView setContentInset:UIEdgeInsetsMake(0.f, 0.f, _keyboardFrame.size.height, 0.f)];

保持高度限制并连接sockets:

 @property (weak, nonatomic) IBOutlet NSLayoutConstraint *CS_TableView_Height; 

看一下本教程的示例3。

使用NSNotificationCenter捕获键盘事件来更新视图的高度:

 - (void)viewWillAppear:(BOOL)animated { // register for keyboard notifications [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide) name:UIKeyboardWillHideNotification object:nil]; } - (void)viewWillDisappear:(BOOL)animated { // unregister for keyboard notifications while not visible. [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:UIKeyboardWillHideNotification object:nil]; } 

您可能还希望看一下这个问题的接受答案,以获得一些灵感。

所以最后,你应该得到这样的东西:

 - (void)keyboardWillShow { self.CS_TableView_Height.constant = 500;//For example [self.tableView setNeedsUpdateConstraints]; } - (void)keyboardWillHide { self.CS_TableView_Height.constant = 568;// iPhone5 height [self.tableView setNeedsUpdateConstraints]; } 

首先,您不应添加上下约束和高度约束。 如果屏幕大小发生变化,应用程序将崩溃(除非其中一个约束具有较低优先级,在这种情况下它将被删除)。

其次,在您的keyboardDidAppear通知方法中,您只需将底部空间更改为[myView setNeedsDisplay]的常量值并调用[myView setNeedsDisplay]

编辑:您不会在becomeFirstResponder之后执行setNeedsDisplay。 您可以将self添加为keyboardWillShow / keyboardWillHide通知的观察者,并在该方法中更新约束并调用setNeedsDisplay

看看这篇苹果post , Listing 5-1 Handling the keyboard notificationsListing 5-2 Additional methods for tracking the active text field提供了代码。