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

时间:2014-06-02 06:58:54

标签: ios uitableview interface-builder autolayout

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

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

  • 超级视图的顶层空间:0
  • 追踪空间到superview:0
  • 领导空间到superview:0
  • 底层空间到superview:0
  • 高度等于= 424

我认为最快的方法是删除高度和底部空间约束,并在调用keyboardDidAppear通知时调整代码中的实际视图大小,但有没有其他方法可以做到这一点?

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

3 个答案:

答案 0 :(得分:17)

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

swift 4.2

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

let notificationTokenKeyboardWillHide = NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: nil) { (_) in
    UIView.animate(withDuration: CATransaction.animationDuration(), animations: {
        self.scrollView?.contentInset = .zero
    }, completion: nil)
}

注意事项1: scrollView此处代表UIScrollView的任何子集,例如UITableViewUICollectionView等等......

注意-2: 当您即将发布时,您需要通过调用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)];

答案 1 :(得分:2)

保持身高限制并连接插座:

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

查看this tutorial的示例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];
}

您可能还需要查看this question接受的答案,了解一些灵感。

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

- (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];
}

答案 2 :(得分:0)

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

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

编辑:你不能在doneFirstResponder之后执行setNeedsDisplay。您添加self作为keyboardWillShow / keyboardWillHide次通知的观察者,并在该方法中更新约束并调用setNeedsDisplay

查看this apple postListing 5-1 Handling the keyboard notificationsListing 5-2 Additional methods for tracking the active text field提供代码。