[英]How do I get scrollToRow to work within a UITableView on keyboard events?
I have a tableView in my view controller and I have it such that the tableView shrinks and expands depending on whether the keyboard is on the screen or off the screen.我的视图控制器中有一个 tableView 并且我有它,这样 tableView 会根据键盘是在屏幕上还是屏幕外来收缩和扩展。 When the tableView shrinks, I want it to scroll to the bottom row but I can't get this to work.当 tableView 缩小时,我希望它滚动到底行,但我无法让它工作。
Currently, I have the following:目前,我有以下几点:
@objc func keyboardAppears(notification: Notification) {
if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect {
bottomConstraint.constant = -1 * keyboardFrame.height
view.loadViewIfNeeded()
tableView.scrollToRow(at: IndexPath(row: 10, section: 0), at: .top, animated: true)
}
}
I also tried putting it in the main thread.我也试过把它放在主线程中。 This got it to work the first time the keyboard went up only.这使它在第一次键盘上升时起作用。 The code looked as follows:代码如下所示:
@objc func keyboardAppears(notification: Notification) {
if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect {
bottomConstraint.constant = -1 * keyboardFrame.height
view.loadViewIfNeeded()
parentView.scrollUp()
}
}
func scrollUp() {
DispatchQueue.main.async {
self.entrySpace.scrollToRow(at: IndexPath(row: self.data.count - 1, section: 0), at: .top, animated: true)
}
}
UPDATE:更新:
The following works after a letter is typed in the field (I want it to work right when the keyboard comes up)在字段中输入一个字母后,以下工作(我希望它在键盘出现时正常工作)
NOTE: this is the UITableViewCell class because the cell is the last item in the UITableView注意:这是 UITableViewCell 类,因为单元格是 UITableView 中的最后一项
import UIKit
class EntryButtonCell: UITableViewCell {
//the textView for new entries
var entryCell = UITextView()
//Reference to the parent table
var parentTable = UITableView()
//Reference to the parent view (the one that holds the table view)
var parentView = ParentVC()
var bottomConstraint = NSLayoutConstraint()
//Initialization
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
//set this cell as the delegate for the entry textView
entryCell.delegate = self
//deactivate interaction with the cell so the user can interact with the textView
contentView.isUserInteractionEnabled = false
//set up the textView
prepTextView()
//set the notification for the keyboard events
setKeyboardObservers()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//deinitialization
deinit {
//remove the keyboard observers
removeKeyboardObservers()
}
func prepTextView() {
//just did the constraints here
//removing to save space
}
func scrollToBottom() {
DispatchQueue.main.async { [weak self] in
guard let data = self?.parentView.data else { return }
let indexPath = IndexPath(row: data.count, section: 0)
self?.parentTable.scrollToRow(at: indexPath, at: .bottom, animated: true)
}
}
//set the keyboard notification
private func setKeyboardObservers() {
//add keyboardWillShowNotification
NotificationCenter.default.addObserver(self, selector: #selector(keyboardAppears(notification:)), name: UIResponder.keyboardWillShowNotification, object: nil)
//add keyboardWillHideNotification
NotificationCenter.default.addObserver(self, selector: #selector(keyboardDisappears(notification:)), name: UIResponder.keyboardWillHideNotification, object: nil)
}
//deactivate the keyboard notifications
private func removeKeyboardObservers() {
//deactivate keyboardWillShowNotification
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillShowNotification, object: nil)
//deactivate keyboardWillHideNotification
NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
}
//run when keyboard shows
@objc func keyboardAppears(notification: Notification) {
if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect {
scrollToBottom()
bottomConstraint.constant = -1 * keyboardFrame.height
parentTable.layoutSubviews()
parentView.loadViewIfNeeded()
}
}
@objc func keyboardDisappears(notification: Notification) {
tableBottomConstraint.constant = -100.0
parentView.loadViewIfNeeded()
}
//Took out a few of the textView methods to save space
}
I have tested the following code based on your logic so that you just add a few lines to get it to work.我已经根据您的逻辑测试了以下代码,因此您只需添加几行即可使其工作。
// MARK: Keyboard Handling
@objc func keyboardWillShow(notification: Notification)
{
if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect
{
tableView.reloadData()
scrollToBottom()
tableBottomConstraint.constant = -1 * (keyboardFrame.height + 100)
loadViewIfNeeded()
}
}
@objc func keyboardWillHide(notification: Notification)
{
tableBottomConstraint.constant = -100.0
loadViewIfNeeded()
}
func scrollToBottom()
{
DispatchQueue.main.async { [weak self] in
guard let data = self?.data else { return }
let indexPath = IndexPath(row: data.count - 1, section: 0)
self?.tableView.scrollToRow(at: indexPath, at: .bottom, animated: true)
}
}
The output of my code will be something like this:我的代码的输出将是这样的:
After updating a constraint, you have to commit the update by calling the layoutSubview() and after that you can call the scrollToRow(at:at:animated) method.更新约束后,您必须通过调用 layoutSubview() 提交更新,然后您可以调用 scrollToRow(at:at:animated) 方法。
@objc func keyboardAppears(notification: Notification) {
if let keyboardFrame = notification.userInfo?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect {
bottomConstraint.constant = -keyboardFrame.height
view.layoutSubviews()
self.entrySpace.scrollToRow(at: IndexPath(row: self.data.count - 1, section: 0), at: .top, animated: true)
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.