Swift:tableView 中的最后一个单元格在不应该禁用 userInteraction 时被禁用
Swift: Last cell in tableView gets userInteraction disabled when it shouldn't
我有一个包含两个部分的表视图,我希望禁用第二部分单元格内的 textView 的用户交互(这些已完成,用户不能编辑他们的文本)。下面来自 cellForRowAt 的代码工作正常,但是当我添加一个新单元格(它被添加到第 0 节的末尾时,这最终导致 userInteraction 被禁用,我不知道为什么。重新加载 viewController(关闭页面并再次打开)似乎解决了问题。
关于为什么会发生这种情况的任何想法或想法?
提前致谢。
如果需要更多详细信息,我很乐意与您分享。
这是来自 cellForRow
的代码
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ActionCell", for: indexPath) as! StepCell
if indexPath.section == 0 {
cell.label.alpha = 1
// This code is needed to remove the strikethrough from this cell
let attr = NSMutableAttributedString(attributedString: (cell.label.attributedText)!)
let originalRange = NSMakeRange(0, attr.length)
attr.setAttributes([:], range: originalRange)
cell.label.attributedText = attr
cell.label.attributedText = NSMutableAttributedString(string: "", attributes: [:])
cell.label.text = goals[selectedCell].steps![indexPath.row].title
cell.checkbox.image = UIImage(named: "unticked")
cell.focus.isHidden = false
} else {
cell.label.alpha = 0.5
cell.label.attributedText = goals[selectedCell].completedSteps![indexPath.row].title.withStrikethroughStyle(.single)
cell.checkbox.image = UIImage(named: "ticked")
cell.focus.isHidden = true
cell.label.isUserInteractionEnabled = false
}
cell.label.textContainerInset = UIEdgeInsets(top: 20, left: -6, bottom: 20, right: 0);
cell.label.textColor = .white
cell.label.tintColor = UIColor(named: "Yellow")
cell.label.keyboardAppearance = .dark
cell.label.font = UIFont.boldSystemFont(ofSize: 18)
cell.label.disableKeyboardAccessory()
cell.label.delegate = self
cell.delegate = self
print("For \(indexPath) user intercation enabled is \(cell.label.isUserInteractionEnabled)")
return cell
}
这里是添加新单元格的代码
@IBAction func plusTU(_ sender: Any) {
goals[selectedCell].steps?.append(Step(title: ""))
let numberOfCells = tableview.numberOfRows(inSection: 0)
tableview.reloadData()
tableview.layoutIfNeeded()
DispatchQueue.main.asyncAfter(deadline: .now()+0.2) {
let cell = self.tableview.cellForRow(at: IndexPath.init(row: numberOfCells, section: 0)) as? StepCell
cell?.label.becomeFirstResponder()
}
let indexPath = IndexPath(row: goals[selectedCell].steps!.count - 1, section: 0)
tableview.scrollToRow(at: indexPath, at: .bottom, animated: true)
progressBar.configure(goalsIndex: selectedCell)
configureCompleteGoalButton(buttonHeight: completeGoalButtonHeight, progressBarHeight: progressBarHeight, progressBar: progressBar)
}
如果相关,我有一个如下所示的 textView 委托:
extension GoalDetails: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
let cell = textView.superview?.superview as? StepCell
let indexPath = tableview.indexPath(for: cell!)
goals[selectedCell].steps![indexPath!.row].title = textView.text
resizeTableViewCell()
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "\n" || text == "\t" {
textView.resignFirstResponder()
return false
}
return true
}
func textViewDidEndEditing(_ textView: UITextView) {
writeJSONGoals()
}
func textViewDidBeginEditing(_ textView: UITextView) {
if descriptionExists == true {
descriptionHeight.isActive = true
descriptionExpanded = false
}
}
}
它调用的函数是这样的:
func resizeTableViewCell(){
tableview.beginUpdates()
tableview.endUpdates()
tableview.layoutIfNeeded()
}
页面看起来像这样,我还附上了来自 cellForRow 的控制台打印
细胞得到重复利用。您需要确保将 isUserInteractionEnabled
明确设置为所有单元格的适当值,以确保它们没有使用过时的值。
对于第 0
部分的单元格,您需要设置:
cell.label.isUserInteractionEnabled = true
我有一个包含两个部分的表视图,我希望禁用第二部分单元格内的 textView 的用户交互(这些已完成,用户不能编辑他们的文本)。下面来自 cellForRowAt 的代码工作正常,但是当我添加一个新单元格(它被添加到第 0 节的末尾时,这最终导致 userInteraction 被禁用,我不知道为什么。重新加载 viewController(关闭页面并再次打开)似乎解决了问题。
关于为什么会发生这种情况的任何想法或想法? 提前致谢。
如果需要更多详细信息,我很乐意与您分享。
这是来自 cellForRow
的代码func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ActionCell", for: indexPath) as! StepCell
if indexPath.section == 0 {
cell.label.alpha = 1
// This code is needed to remove the strikethrough from this cell
let attr = NSMutableAttributedString(attributedString: (cell.label.attributedText)!)
let originalRange = NSMakeRange(0, attr.length)
attr.setAttributes([:], range: originalRange)
cell.label.attributedText = attr
cell.label.attributedText = NSMutableAttributedString(string: "", attributes: [:])
cell.label.text = goals[selectedCell].steps![indexPath.row].title
cell.checkbox.image = UIImage(named: "unticked")
cell.focus.isHidden = false
} else {
cell.label.alpha = 0.5
cell.label.attributedText = goals[selectedCell].completedSteps![indexPath.row].title.withStrikethroughStyle(.single)
cell.checkbox.image = UIImage(named: "ticked")
cell.focus.isHidden = true
cell.label.isUserInteractionEnabled = false
}
cell.label.textContainerInset = UIEdgeInsets(top: 20, left: -6, bottom: 20, right: 0);
cell.label.textColor = .white
cell.label.tintColor = UIColor(named: "Yellow")
cell.label.keyboardAppearance = .dark
cell.label.font = UIFont.boldSystemFont(ofSize: 18)
cell.label.disableKeyboardAccessory()
cell.label.delegate = self
cell.delegate = self
print("For \(indexPath) user intercation enabled is \(cell.label.isUserInteractionEnabled)")
return cell
}
这里是添加新单元格的代码
@IBAction func plusTU(_ sender: Any) {
goals[selectedCell].steps?.append(Step(title: ""))
let numberOfCells = tableview.numberOfRows(inSection: 0)
tableview.reloadData()
tableview.layoutIfNeeded()
DispatchQueue.main.asyncAfter(deadline: .now()+0.2) {
let cell = self.tableview.cellForRow(at: IndexPath.init(row: numberOfCells, section: 0)) as? StepCell
cell?.label.becomeFirstResponder()
}
let indexPath = IndexPath(row: goals[selectedCell].steps!.count - 1, section: 0)
tableview.scrollToRow(at: indexPath, at: .bottom, animated: true)
progressBar.configure(goalsIndex: selectedCell)
configureCompleteGoalButton(buttonHeight: completeGoalButtonHeight, progressBarHeight: progressBarHeight, progressBar: progressBar)
}
如果相关,我有一个如下所示的 textView 委托:
extension GoalDetails: UITextViewDelegate {
func textViewDidChange(_ textView: UITextView) {
let cell = textView.superview?.superview as? StepCell
let indexPath = tableview.indexPath(for: cell!)
goals[selectedCell].steps![indexPath!.row].title = textView.text
resizeTableViewCell()
}
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "\n" || text == "\t" {
textView.resignFirstResponder()
return false
}
return true
}
func textViewDidEndEditing(_ textView: UITextView) {
writeJSONGoals()
}
func textViewDidBeginEditing(_ textView: UITextView) {
if descriptionExists == true {
descriptionHeight.isActive = true
descriptionExpanded = false
}
}
}
它调用的函数是这样的:
func resizeTableViewCell(){
tableview.beginUpdates()
tableview.endUpdates()
tableview.layoutIfNeeded()
}
页面看起来像这样,我还附上了来自 cellForRow 的控制台打印
细胞得到重复利用。您需要确保将 isUserInteractionEnabled
明确设置为所有单元格的适当值,以确保它们没有使用过时的值。
对于第 0
部分的单元格,您需要设置:
cell.label.isUserInteractionEnabled = true