这是我的footerView,名为FooterTableViewCell。我有一个名为SurveyAnswerTableViewCellDelegate的协议。它的父级是AddQuestionViewController。
当我点击页脚视图时,我会触发@IBAction。
@objc protocol SurveyAnswerTableViewCellDelegate: AnyObject {
func textSaved(_ text: String)
}
class FooterTableViewCell: UITableViewHeaderFooterView {
var parentVC: AddQuestionViewController!
@IBAction func addNewTapped(_ sender: Any) {
print("tapped")
let newTag = model.tag + 1
parentVC.addNewAnswer()
}
此按钮操作触发AddQuestionViewController
class AddQuestionViewController: SurveyAnswerViewDelegate, UITextFieldDelegate, UITableViewDelegate, SurveyAnswerTableViewCellDelegate {
var answers: [SurveyAnswerModel] = []
var savedText : String = ""
static var delegate: SurveyAnswerTableViewCellDelegate?
我尝试创建一个空字符串,并将一个新的答案附加到我的数组中。但这里的文本总是"&";。
func addNewAnswer() {
let newAnswer = SurveyAnswerModel(answer: savedText, tag: 0)
self.answers.append(newAnswer)
self.tableView.reloadData()
}
func textSaved(_ text: String) {
savedText = text
}
我试图读取的文本字段在SurveyAnswerTableViewCell中,同时在我调用的设置函数的tableview中设置单元格。
class SurveyAnswerTableViewCell: UITableViewCell {
@IBOutlet weak var textField: UITextField!
weak var delegate: SurveyAnswerTableViewCellDelegate?
var parentVC: AddQuestionViewController!
func setup() {
if let text = self.textField.text {
self.delegate?.textSaved(textField.text!)
}
}
extension AddQuestionViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(forIndexPath: indexPath) as SurveyAnswerTableViewCell
cell.parentVC = self
cell.setup()
return cell
}
我如何才能成功地将该文本发送到AddQuestionViewController,以便它添加一个带有正确字符串的新答案
有一些因素使其无法工作。
- 在对单元格进行排队以供重用后,直接调用
SurveyAnswerTableViewCell
的setup()
函数。此时它还没有(重新(出现在屏幕上,因此用户没有机会在文本字段中输入任何内容 - 您当前没有将
SurveyAnswerTableViewCell
的委托属性设置为任何内容,因此即使文本字段具有有效输入,委托也将是nil
,而delegate?.textSaved(textField.text!)
也不会执行任何操作 - 前面这两点都意味着
AddQuestionViewController .savedText
的值永远不会从空字符串中更新。因此,当addNewAnswer()
尝试读取它时,它总是会看到那个空字符串
与其在单元格出列时读取文本字段,不如在用户完成键入后保存文本字段值。
为此,请使单元格符合UITextFieldDelegate并实现textFieldDidEndEditing(_:)
方法。然后,您可以从该方法中调用已经必须保存文本的委托方法请确保VC已经设置了单元格的委托属性,否则将无法执行任何操作
VC本身不应具有SurveyAnswerTableViewCellDelegate
类型的委托属性。它将用作委托,而不是具有一个。如果这不太合理,我建议查看一些关于委派模式的在线资源。
因此,请确保ViewController符合SurveyAnswerTableViewCellDelegate
,然后将单元格的委托值设置为VC
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(forIndexPath: indexPath) as SurveyAnswerTableViewCell
cell.delegate = self
return cell
}
顺便说明一下,页脚和单元格都不应该引用父视图控制器。一般来说,避免子视图知道其父视图是很好的。当组件之间存在双向知识共享时,事情会变得不必要地复杂,这会使子视图的可重用性大大降低。我建议为页脚创建一个委托,并从页脚和单元格中删除parentVC
属性。
以下是正在发生的事情:
- 点击按钮
- 调用
addNewTapped(_:)
- 调用
addNewAnswer()
newAnswer
附加到answers
- 调用
tableView.reloadData()
- 使用新的/空的文本字段重新生成单元格(因此永远不会调用
delegate.textSaved
(
所以我不确定你想做什么,但我认为有两条可能的路线:
- 单独存储
UITextField
,并将它们添加到表单元格中,这样它们就不会被表重载删除 - 使
AddQuestionViewController
与UITextFieldDelegate
一致,并将其设置为文本字段的委托,以观察文本字段文本的变化(如果您只使用1个文本字段,则可以在那里设置savedText
(