简体   繁体   English

从协议中委派函数未被调用

[英]Delegate function from protocol not being called

I have a previously working delegate and protocol that since the conversion to Swift 3 is no longer being called. 我有一个以前工作的委托和协议,因为不再调用转换到Swift 3。

protocol TaskCellDelegate {
    func doneHit(_ cell : TaskCell)
}

class TaskCell : UITableViewCell {

    var delegate : TaskCellDelegate?

    @IBOutlet weak var label: UILabel!
    @IBOutlet weak var detailLabel: UILabel!
    @IBOutlet weak var _checkBox: M13Checkbox!


    override func awakeFromNib() {
        super.awakeFromNib()
        let tap = UITapGestureRecognizer(target: self, action: #selector(TaskCell.buttonClicked(_:)))
        tap.numberOfTapsRequired = 1
        _checkBox.addGestureRecognizer(tap)
        _checkBox.isUserInteractionEnabled = true
        _checkBox.markType = .checkmark
        _checkBox.boxType = .circle
        _checkBox.stateChangeAnimation = .expand(.fill)
    }
    func buttonClicked(_ sender:UITapGestureRecognizer) {
        delegate?.doneHit(self)
    }
}

As you can see, when the _checkBox is tapped it should call the function doneHit in my class (not added because it doesn't seem necessary but I can) but I set a breakpoint and it's never called. 正如你所看到的,当点击_checkBox时,它应该在我的类中调用函数doneHit(没有添加,因为它似乎没有必要,但我可以)但是我设置了一个断点并且它从未被调用过。 I've set my delegate and conformed to the protocol in my class but nothing is happening. 我已经设置了我的代表并且符合我班级的协议,但没有任何事情发生。 The doneHit function is supposed to update my backend but its not being called. doneHit函数应该更新我的后端,但它没有被调用。 If you need more info, I can provide. 如果您需要更多信息,我可以提供。

Edit 1: 编辑1:

class TasksTVC: UITableViewController, TaskCellDelegate {

    func doneHit(_ cell:TaskCell) {
        if let indexPath = self.tableView.indexPath(for: cell) {
            task = tasksInSectionArray[indexPath.section][indexPath.row]
            if task.done == false {
                cell._checkBox.setCheckState(.checked, animated: true)
                task.done = true
                task.completedBy = user
                cell.detailLabel.text = "Completed By: \(task.completedBy)"
                cell.label.textColor = UIColor.gray
                print("cell checked")
            }
            else {
                cell._checkBox.setCheckState(.unchecked, animated: true)
                task.done = false
                task.completedBy = ""
                cell.detailLabel.text = ""
                cell.label.textColor = UIColor.black
                print("cell unchecked")

            }
            fb.updateTaskDoneBool(ref, taskID: task.id, taskDone: task.done)
            fb.updateTaskCompletedBy(ref, taskID: task.id, taskCompletedBy: task.completedBy)
        }

    }

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "TaskCell", for: indexPath) as! TaskCell
        cell.selectionStyle = .none
        task = tasksInSectionArray[indexPath.section][indexPath.row]
        cell.label.text = task.title
        if task.done == true {
            cell._checkBox.setCheckState(.checked, animated: true)
            cell.detailLabel.text = "Completed By: \(task.completedBy)"
            cell.label.textColor = UIColor.gray
        }
        else {
            cell._checkBox.setCheckState(.unchecked, animated: true)
            cell.detailLabel.text = ""
            cell.label.textColor = UIColor.black

        }
        doneHit(cell)
        cell.delegate = self
        return cell
    }}

Looks like you didn't set correctly the delegate property in your TaskCell instance , I will make a very basic example hopefully it helps you to catch the issue: 看起来你没有正确设置TaskCell实例中的delegate属性,我将做一个非常基本的例子,希望它可以帮助你解决问题:

Result (Edited) 结果(已编辑)

Code

TableViewController TableViewController

import UIKit

protocol TaskCellDelegate {
  func doneHit(_ cell: TaskCell)
}

class TableViewController: UITableViewController, TaskCellDelegate {
  func doneHit(_ cell: TaskCell) {
    let alert = UIAlertController(
                    title: "Info",
                    message: "button touched in cell",
                    preferredStyle: .alert
                )
    present(alert, animated: true, completion: nil)
  }
}

extension TableViewController {
  override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1
  }

  override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! TaskCell
    cell.delegate = self // probably you forgot to set this part?

    return cell
  }
}

TaskCell (Edited) TaskCell (已编辑)

Instead creating a new UITapGestureRecognizer to attach to the checkbox , you can use addTarget method to attach event handler for the UIControlEvents.valueChanged value. 而是创建一个新的UITapGestureRecognizer以附加到复选框 ,您可以使用addTarget方法为UIControlEvents.valueChanged值附加事件处理程序。

import UIKit
import M13Checkbox

class TaskCell: UITableViewCell {

  var delegate: TaskCellDelegate?

  @IBOutlet weak var checkbox: M13Checkbox!

  override func awakeFromNib() {
    super.awakeFromNib()

    checkbox.addTarget(self, action: #selector(buttonClicked), for: .valueChanged)
  }


  func buttonClicked() {
    delegate?.doneHit(self)
  }

}

There are following cases if delegate is not being called: 如果没有调用委托,则存在以下情况:

  1. The action: buttonClicked is not being called. 动作: buttonClicked未被调用。
  2. The View Controller not Conforming to the protocol. 视图控制器不符合协议。

     class ViewController: UIViewController, TaskCellDelegate { 
  3. The protocol method not implemented inside View Controller. 协议方法未在View Controller中实现。

     func doneHit(_ cell : TaskCell) { print("delegate implementation called") } 
  4. Delegate not assigned in cellForRowAtIndexPathMethod: 未在cellForRowAtIndexPathMethod:分配的委托cellForRowAtIndexPathMethod:

     cell.delegate = self 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM