使用“自动布局”弹出键盘时,如何调整视图大小
我有一个视图(在这种情况下是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 notifications
和Listing 5-2 Additional methods for tracking the active text field
提供了代码。