防止键盘阻塞单元格
Posted
技术标签:
【中文标题】防止键盘阻塞单元格【英文标题】:Keep keyboard from blocking cell 【发布时间】:2016-11-28 18:09:07 【问题描述】:我的应用程序显示一个表单,在某些单元格上有可以输入信息的文本字段。如果单元格位于屏幕底部,则单元格将被完全屏蔽,这意味着您无法看到您正在回答的问题是什么。我的 UITableView 嵌入在 UIViewController 中。
我已经查看了许多为这个问题提供答案的线程并实现了一些代码。如果我能让这个方法起作用,我相信我的代码会起作用:
func textFieldDidBeginEditing(_ textField: UITextField)
if (self.tableView.contentOffset.y == 0)
self.tableView.scrollToRow(at: self.tableView.indexPath(for: ), at: UITableViewScrollPosition, animated: true)
现在我正在尝试解决获取活动单元格的问题,以便可以将其输入到self.tableView.indexPath(for: )
。
我该怎么做呢?这是在键盘上方移动视图的正确方法吗?
【问题讨论】:
我已使用IQKeyboardManager 移动文本字段,以免它们被阻止。到目前为止,它对我来说效果很好。 你能告诉我表单是动态的还是静态的,如果是静态的,那么无需任何代码就可以很容易地实现它。 使用键盘通知处理此类问题 【参考方案1】:在您的应用中使用https://github.com/hackiftekhar/IQKeyboardManager。它将保持文本字段和键盘设置本身正常。
【讨论】:
【参考方案2】:在 viewWillAppear 上,您注册了 UIKeyboardWillShow 和 UIKeyboardWillHide 通知:
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name:NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillHide), name:NSNotification.Name.UIKeyboardWillHide, object: nil)
然后在keyboardWillShow上你会得到键盘的框架并改变tableView的插图
func keyboardWillShow(notification: Notification)
guard let keyboardFrame = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue else return
let convertedFrame = view.convert(keyboardFrame, from: nil)
tableView.contentInset.bottom = convertedFrame.height
然后在keyboardWillHide 中将底部插图更改回0,如果需要,将tableView 滚动回某一行。这会将其滚动回位于 tableView 顶部的第一行。
func keyboardWillHide(notification: Notification)
tableView.contentInset.bottom = 0
tableView.scrollToRow(at: IndexPath(row: 0, section: 0), at: .top, animated: true)
这也是一种很好的方法,因为它可以让你的 textField 委托不被影响布局的代码弄乱。
我相信我在某处读到过,对于某些通知(包括键盘通知),您不需要将自己移除为观察者,但为了安全起见,您应该根据具体情况将它们放入 viewWillDisappear 或 deinit 中
deinit
NotificationCenter.default.removeObserver(self, name: Notification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: Notification.Name.UIKeyboardWillHide, object: nil)
// If you don't have any other notifications you wan't to keep observing you can remove yourself from all observers by using this one line
// NotificationCenter.default.removeObserver(self)
【讨论】:
【参考方案3】:使用通知中心。
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillAppear), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardWillDisappear), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
【讨论】:
【参考方案4】:查看我对这篇帖子的回答 ios Support External Keyboard Without Displaying One
另外,对于 tableView,我使用类似这样的东西来通过键盘适当地显示单元格。
func textFieldDidBeginEditing(_ textField: UITextField)
tableView.isScrollEnabled = false
var path: IndexPath?
path = theIndexPathOfTheCellWithTheTextField
if path != nil
let rect = CGRect(x: 0, y: 0, width: tableView.frame.width, height: tableView.frame.height)
tableView.tableFooterView = UIView(frame: rect)
UIView.animate(withDuration: 0.6, animations:
[weak self] in
self?.tableView.scrollToRow(at: path!, at: .top, animated: false)
, completion: nil)
func textFieldDidEndEditing(_ textField: UITextField)
tableView.tableFooterView = UIView()
tableView.isScrollEnabled = true
如果您有 tableView 的 tableFooterView 的 UI,则这部分代码可能需要根据页脚视图的可用大小进行更改或删除。
编辑 - 更多信息: 为了制作 indexPath,您有几个选项。如果您像这样知道单元格的位置,则可以对其进行硬编码:
//This works where neither theRowInt or theSectionInt are negative.
IndexPath(row: theRowInt, section: theSectionInt)
//So this would be the first section/first row
IndexPath(row: 0, section: 0)
下一个方法是基于你通过 textField 找到的单元格:
let textFieldCell = textField.superview.superview.superview as! UITableViewCell
let indexPath = self.tableView.indexPathForCell(textFieldCell)
假设您的超级视图数量正确,则此方法有效。如果您将 textField 直接放入 contentView,那么这应该是自 iOS 7 以来的正确数字。如果它崩溃,不仅仅是改变 .superviews 的数量直到它工作。
还有其他方法,但如果您对它们感兴趣,请自行研究。 Here 是一个很好的堆栈溢出帖子。
【讨论】:
如何获得IndexPathOfTheCellWithTheTextField?好像我能弄清楚我可以使用上面的代码运行。 所以我在我的和另一个都没有运气之后尝试了这个解决方案......而且这个也不起作用。当我单击文本字段时,tableview 根本不会滚动。只是更多的信息。我正在使用我创建的自定义 tableviewcells。 uitableview 放置在我的 uiviewcontroller 中的 2 个 uiview 之间。我不知道这是否会影响它正确滚动。关于如何调试这个有什么想法吗?【参考方案5】:到目前为止,这个问题最简单的解决方案是使用 UITableViewController
而不是带有 tableView 属性的 UIViewController
。
它会自动为您处理。我很清楚在某些情况下您不能使用UITableViewController
,但如果可能的话,您应该这样做。使用在常规控制器中嵌入 UITableViewController
的容器视图控制器即使在更复杂的情况下也可以实现。
【讨论】:
以上是关于防止键盘阻塞单元格的主要内容,如果未能解决你的问题,请参考以下文章
如何防止超过电子表格单元格字符限制的 CSV 数据溢出到相邻单元格?