以下是使用UITextFields和高UITableViewCells处理滚动的最佳方法吗?
我有一个UITableView,里面有高大的单元格和UITextFields,从上到下分布。高,我的意思是当键盘弹出时,整个单元格都无法显示。
当依赖于默认行为时,如果选择位于单元格顶部的UITextField,则自动滚动不起作用。这似乎是非常基本的,并始终滚动到底部位置,这导致最顶层的UITextFields(包括所选的一个)被隐藏。
因此,我使用UIKeyboardWillShow / UIKeyboardDidShow通知。
我首先尝试将此行为仅用于顶部的UITextFields,否则依赖于默认行为,但由于某种原因,自动滚动不再可靠,所以我选择了手动滚动。
这是我正在使用的(有点“经典”)代码。 基本上,我只是告诉tableview滚动到哪里,根据所选的UITextField更改UITableViewScrollPosition
var scrollTo: (indexPath: IndexPath, position: UITableViewScrollPosition)?
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
registerForKeyboardNotifications()
}
override func viewWillDisappear(_ animated: Bool) {
unregisterForKeyboardNotifications()
super.viewWillDisappear(animated)
}
func registerForKeyboardNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardDidShow), name: NSNotification.Name.UIKeyboardDidShow, object: nil)
}
func unregisterForKeyboardNotifications() {
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.removeObserver(self, name: NSNotification.Name.UIKeyboardDidShow, object: nil)
}
func keyboardWillShow() {
tableView.isScrollEnabled = scrollTo == nil
}
func keyboardDidShow() {
guard let scrollTo = scrollTo else { return }
self.scrollTo = nil
tableView.scrollToRow(at: scrollTo.indexPath, at: scrollTo.position, animated: true)
tableView.isScrollEnabled = true
}
/// Textfields are tagged to allow UITextFieldDelegate method identification
/// I renamed each text field according to its location in the cell for sake of clarity
enum CellTextField: Int {
case topFieldA = 1, topFieldB, middleFieldA, bottomFieldA, bottomFieldB
static let multiplier = 10
static func identifiersFrom(cellTag: Int) -> (cellTextField: CellTextField, indexPath: IndexPath)? {
guard let cellTextField = CellTextField(rawValue: cellTag % CellTextField.multiplier) else {
return nil
}
let indexPath = IndexPath(row: cellTag / CellTextField.multiplier, section: 0)
return (cellTextField, indexPath)
}
func tagFor(row: Int) -> Int {
return row * CellTextField.multiplier + self.rawValue
}
}
/// When the textfield is selected, I retrieve the indexPath from the textfield tag
/// (set by tableView(tableView:cellForRowAt indexPath:)) and set the most relevant
//// scrollTo position according to the textfield position in the cell
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
guard let identifiers = CellTextField.identifiersFrom(cellTag: textField.tag) else { return true }
switch identifiers.cellTextField {
case .topFieldA, . topFieldB:
scrollTo = (identifiers.indexPath, .top)
case . middleFieldA:
scrollTo = (identifiers.indexPath, .middle)
case .bottomFieldA, . bottomFieldB:
scrollTo = (identifiers.indexPath, .bottom)
}
return true
}
以上代码运行正常,对于有高细胞的罪行来说,这似乎是一个很大的开销。或者这是处理这个问题的正确方法吗?
答案 0 :(得分:0)
我将缺少答案:是的,这是处理它的正确方法。