我有一个实现为UITableViewController的文本输入表单,其中表单中的每个字段都是tableview中单元格的子视图。在我的键盘上,我有“next”和“prev”按钮执行预期操作,并在文本字段之前调用一个单元格或在当前第一个响应者之后的一个单元格上调用yesFirstResponder()。
当按下“next”时,此调用始终成功:对下一个字段的finallyFirstResponder()的调用返回true,即使该单元格当前位于屏幕底部之下。但是,当按下“prev”时,如果该字段的父视图当前在屏幕上可见,则对前一个字段的lastFirstResponder()的调用返回true,但当它在屏幕顶部上方时返回false。
我考虑并消除了一些原因:
1)表视图使用静态单元格,因此目标字段的父单元格不会被回收再使用。它始终是视图层次结构的一部分,控制器会保留对它的引用。
2)我要求成为第一响应者的字段的canBecomeFirstResponder属性返回true,即使不可见。
3)当前的第一响应者没有通过拒绝放弃第一响应者状态来阻止它。第一响应者== nil当时在相关字段上调用了firstFirstResponder()。
4)我要求成为第一响应者的字段的委托在为相关文本字段调用其shouldBeginEditing(_)字段时返回“true”。
我的问题是,上面给出(1) - (4),可能导致causeFirstResponder()返回'false'的原因是什么?我已经尝试但未能成功找到有关UIResponder实现该方法的更多细节。
这是prev press的处理程序以及当时的状态。 (while循环仅用于调试。)
func keyboardControls(_ keyboardControls: BSKeyboardControls, selectedField field: UIView, inDirection direction: BSKeyboardControlsDirection) {
var loopCount = 1
let mainWindow = AppDelegate.appDelegate().window!
while field.isFirstResponder == false {
print(loopCount) // will print from 1 to overflow
print(field.canBecomeFirstResponder) // prints true
print(field.window == mainWindow) // prints true
print(tableView.subviews.contains(field.superview!.superview!)) // prints true
print(mainWindow.currentFirstResponder()) // prints currently active field on first pass, nil thereafter
field.becomeFirstResponder() // returns false
loopCount += 1
}
}