我有一个显示待办事项的TableViewController
。在控制器中,我制作了一个按钮,当按下该按钮时,将在底部创建一个新的TableViewCell
,它与其他元素一起具有UITextView
。
到目前为止,这就是我所能做到的-
- 点击按钮后创建新单元格
- 使新创建的单元格的文本视图成为第一响应者
然而,从我观察到的情况来看,除了表格中的最后一个单元格不可见(即它在框架下方)之外,一切都运行得很好。在这种情况下,单元格被创建,但没有被创建,第一响应者或其他单元格的文本视图获得光标。
请参见此处的输出-https://drive.google.com/file/d/1mRN8MEO5HBJ3ICUiRE0Yc4ib8tp62MYc/view?usp=sharing
代码是这样的-
import UIKit
class TableViewController: UITableViewController, InboxCellDelegate {
var cell = InboxCell()
override func viewDidLoad() {
super.viewDidLoad()
// Uncomment the following line to preserve selection between presentations
// self.clearsSelectionOnViewWillAppear = false
// Uncomment the following line to display an Edit button in the navigation bar for this view controller.
// self.navigationItem.leftBarButtonItem = self.editButtonItem
tableView.register(UINib(nibName: "InboxCell", bundle: nil), forCellReuseIdentifier: "InboxCell")
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 50
}
@IBAction func inboxAddPressed(_ sender: UIBarButtonItem) {
addRowToEnd()
}
func addRowToEnd() {
Task.tasks.append("")
tableView.beginUpdates()
tableView.insertRows(at: [IndexPath(row: Task.tasks.count - 1, section: 0)], with: .automatic)
tableView.endUpdates()
cell.inboxTaskTextView.becomeFirstResponder()
}
func didChangeText(text: String?, cell: InboxCell) {
self.tableView.beginUpdates()
self.tableView.endUpdates()
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
// #warning Incomplete implementation, return the number of sections
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete implementation, return the number of rows
return Task.tasks.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
cell = tableView.dequeueReusableCell(withIdentifier: "InboxCell", for: indexPath) as! InboxCell
// Configure the cell...
cell.delegate = self
cell.inboxTaskTextView.text = Task.tasks[indexPath.row]
return cell
}
// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
tableView.beginUpdates()
Task.tasks.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
tableView.endUpdates()
}
}
override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return UITableView.automaticDimension
}
}
我试着先滚动到表格的底部,然后让新创建的单元格成为第一个响应者,但没有成功。在这种情况下,只有创建的第一个单元格成为第一个响应者,而后续单元格被创建,但光标保留在第一个单元格中。
以下是我在cell.inboxTaskTextView.becomeFirstResponder()
之前用于滚动的代码块-
DispatchQueue.main.async {
self.tableView.reloadData()
let indexPath = IndexPath(row: Task.tasks.count - 1, section: 0)
self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}
编辑-
在尝试了一段时间后,这是我离解决方案最近的一次。
在Task.tasks.append("")
之后,我添加了以下代码,用于将视图向下滚动到底部-
if tableView.contentSize.height >= tableView.frame.size.height {
DispatchQueue.main.async {
self.tableView.reloadData()
let indexPath = IndexPath(row: Task.tasks.count - 1, section: 0)
self.tableView.scrollToRow(at: indexPath, at: .top, animated: true)
}
}
在这种情况下,新创建的细胞成为第一响应者,但只是暂时的。键盘甚至还没有完全显示出来,它就会在一瞬间被自动关闭。只有在折叠下方创建的单元格才会发生这种情况-即,当表格视图必须向下滚动然后创建新的单元格时。
1条答案
按热度按时间anauzrmj1#
首先,试着保持简单。将断点或
print("indexPath.row = \(indexPath.row)")
放在您已经实现的cellForRow
UITableViewDataSource方法的开头。添加新任务,并查看是否为与新单元格对应的indexPath调用了cellForRow。
如果没有,您可能需要将TableView向上滚动至少44个点或任何需要的点,才能到达新单元格应该已经显示的区域。如果不这样做-单元格可能还没有创建,
cell
很可能引用表视图中的最后一个单元格(或者,如果某些逻辑没有正确实现,它也可能引用池中的单元格)。因此,在使其UITextField
或UITextView
成为第一响应者之前,新细胞必须处于可见区域。如果您知道该单元格已经可见-最好通过
最后,请致电: