【问题标题】:Swift 4.2 Make bottom of tableView move up when keyboard showsSwift 4.2 在键盘显示时使 tableView 的底部向上移动
【发布时间】:2019-06-24 15:21:42
【问题描述】:

虽然我已经搜索过了,但我对如何最好地解决这个问题感到困惑。

我有一个 tableView,其中底部单元格是列表的输入,与苹果提醒的工作方式相同。当列表中的项目太多时,键盘会覆盖列表,我看不到我在输入什么。

我认为我需要更改 table view 的物理大小并确保它在键盘显示时滚动到底部。

有人说键盘观察者,但我发现的大部分代码都已过时,并且在放入 Xcode 时会出错。

NSNotificationCenter Swift 3.0 on keyboard show and hide

这是我能找到的最好的,但我也听说过一些限制,使用 UITableViewController 而不是嵌入 UITableView 等等......

这是我目前的代码:

NotificationCenter.default.addObserver(self, selector: #selector(EntryViewController.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(EntryViewController.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)


@objc func keyboardWillShow(notification: Notification) {
    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        print("notification: Keyboard will show")
        if self.view.frame.origin.y == 0{
            self.view.frame.origin.y -= keyboardSize.height
        }
    }

}

@objc func keyboardWillHide(notification: Notification) {
    if let keyboardSize = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue {
        if self.view.frame.origin.y != 0 {
            self.view.frame.origin.y += keyboardSize.height
        }
    }
}

我认为这会将整个视图向上移动,这意味着安全区域(例如导航栏等)下方有 TableView。在这种方法中,我是否使导航视图不透明?

【问题讨论】:

  • 嵌入tableView只需增加tableview的底部约束即可,无需修改视图大小...
  • 提示:由于 UITableView 是 UIScrollView 的子类,因此您可以使用 contentInset 属性来实现您所需要的。在这里阅读:developer.apple.com/documentation/uikit/uiscrollview/…

标签: ios swift keyboard tableview


【解决方案1】:

一种解决方案(我有时会使用)是在键盘出现/消失时更改tableView 的内容偏移量。我相信这会在您的实例中起作用,而不是像您提到的那样改变 tableView 的约束UIViewControllerUITableViewController。请参阅下面的代码以获取我的建议,希望对您有所帮助!

处理通知:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    NotificationCenter.default.addObserver(self, selector: #selector(EntryViewController.keyboardWillShow), name: UIResponder.keyboardWillShowNotification, object: nil)
    NotificationCenter.default.addObserver(self, selector: #selector(EntryViewController.keyboardWillHide), name: UIResponder.keyboardWillHideNotification, object: nil)
}

override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)

    NotificationCenter.default.removeObserver(self)
}

操作:

@objc func keyboardWillShow(notification: Notification) {
    if let keyboardHeight = (notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? NSValue)?.cgRectValue.height {
        print("Notification: Keyboard will show")
        tableView.setBottomInset(to: keyboardHeight)
    }
}

@objc func keyboardWillHide(notification: Notification) {
    print("Notification: Keyboard will hide")
    tableView.setBottomInset(to: 0.0)
}

扩展:

extension UITableView {

    func setBottomInset(to value: CGFloat) {
        let edgeInset = UIEdgeInsets(top: 0, left: 0, bottom: value, right: 0)

        self.contentInset = edgeInset
        self.scrollIndicatorInsets = edgeInset
    }
}

【讨论】:

  • 虽然这部分工作,我的 tableView 需要手动滚动到正确的位置,以使带有文本字段的单元格出现在键盘顶部。
  • 当 textField 成为第一响应者时,您是否尝试过 tableView.scrollToRow(at: indexPath, at: .middle, animated: true)?如果您使用单元格中的委托,您将能够从该函数中获取对单元格 indexPath 的引用
  • 明白了。我已经有一个委托函数来更新数据模型以保留文本字段内容,所以我在我的委托函数中使用了tableview.scrollToRow 函数,该函数在textViewDidChange(_ textView: UITextView) 函数中被调用。因此,一旦用户键入,它就会滚动以专注于该单元格。
  • 听起来很棒,完美的解决方案!
猜你喜欢
  • 2018-09-27
  • 2019-04-04
  • 2011-07-10
  • 1970-01-01
  • 2013-09-09
  • 1970-01-01
  • 2019-02-22
  • 1970-01-01
  • 2010-12-30
相关资源
最近更新 更多