UITextField和UITableViewCell自动滚动
问题描述:
下面是处理使用UITextFields和高UITableViewCells滚动的最佳方法吗?UITextField和UITableViewCell自动滚动
我有一个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
}
上面的代码工作正常,它只是似乎是一个开销很大的罪有高细胞。或者它是处理这个问题的正确方法?
答
我带你去得不到答案为一体:是的,这是处理它的正确方法。