协议不会向其他 VC 发送值



这是我的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,以便它添加一个带有正确字符串的新答案

有一些因素使其无法工作。

  1. 在对单元格进行排队以供重用后,直接调用SurveyAnswerTableViewCellsetup()函数。此时它还没有(重新(出现在屏幕上,因此用户没有机会在文本字段中输入任何内容
  2. 您当前没有将SurveyAnswerTableViewCell的委托属性设置为任何内容,因此即使文本字段具有有效输入,委托也将是nil,而delegate?.textSaved(textField.text!)也不会执行任何操作
  3. 前面这两点都意味着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属性。

以下是正在发生的事情:

  1. 点击按钮
  2. 调用addNewTapped(_:)
  3. 调用addNewAnswer()
  4. newAnswer附加到answers
  5. 调用tableView.reloadData()
  6. 使用新的/空的文本字段重新生成单元格(因此永远不会调用delegate.textSaved(

所以我不确定你想做什么,但我认为有两条可能的路线:

  • 单独存储UITextField,并将它们添加到表单元格中,这样它们就不会被表重载删除
  • 使AddQuestionViewControllerUITextFieldDelegate一致,并将其设置为文本字段的委托,以观察文本字段文本的变化(如果您只使用1个文本字段,则可以在那里设置savedText(

最新更新