微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Swift 协议委托未在 VC 中触发

如何解决Swift 协议委托未在 VC 中触发

在这里学习协议和委托,但我无法让这个场景发挥作用。我在自定义 tableView Cell 中有两个按钮。我有一个协议方法,我已经把它放在每个按钮块中。当我按下按钮时,打印语句会触发,表明按钮可以工作,但 VC 内部的协议不会触发。

本质上,我试图在每次按下按钮时获取 indexPath.row。但它们都需要分开,我不想使用按钮标签

我尝试了以下方法

Swift protocol delegate not being fired

https://stackoverflow.com/a/60315509/13945484

以及其他发送单元格路径的方式。我尝试在 tableView cellForRowAt indexPath 中使用闭包,这确实可以正常工作,但不允许触发两个不同的按钮。注意:我在另一个单元格中按一个按钮使用相同的配置,这非常有效。我不明白我在这里做错了什么。

风险投资

import UIKit

protocol CellDelegate {
func addEntrants(name: String,company: String)
}
protocol InOutDelegate {
func markIN(cell: UITableViewCell)
func markOUT(cell: UITableViewCell)
}

class EntrySec: UIViewController,CellDelegate,InOutDelegate {

@IBOutlet weak var spaceStatus: UIButton!
@IBOutlet weak var entrantsTable: UITableView!

var entryGrid: [Entrant] = [Entrant(name: "",company: "")]
var entryStatusGrid: [Bool] = [false]

override func viewDidLoad() {
    super.viewDidLoad()
    entrantsTable.dataSource = self
    entrantsTable.register(UINib(nibName: Global.headerCellNibName,bundle: nil),forCellReuseIdentifier: Global.headerCellIdentifier)
    entrantsTable.register(UINib(nibName: Global.bodyCellNibName,forCellReuseIdentifier: Global.bodyCellIdentifier)
}

func addEntrants(name: String,company: String) {
    entryGrid.append(Entrant(name: name,company: company))
    entryStatusGrid.append(false)
    entrantsTable.reloadData()                             // This works as it should
}                                                          // This does not work below

func markIN(cell: UITableViewCell) {
    if let indexpath = self.entrantsTable.returnIndexPath(cell: cell) {
                  print(indexpath)                        // This does not fire
            }
}

func markOUT(cell: UITableViewCell) {                     // Second button protocol
}                                                         // Also does not fire when tried

}

extension EntrySec: UITableViewDataSource {
func tableView(_ tableView: UITableView,numberOfRowsInSection section: Int) -> Int {
    return entryGrid.count
}

func tableView(_ tableView: UITableView,cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    if indexPath.row == 0 {
        let addEntrantCell = entrantsTable.dequeueReusableCell(withIdentifier: 
Global.headerCellIdentifier,for: indexPath) as! AddEntrantCell
        addEntrantCell.delegate = self
        addEntrantCell.entrantNameTextField.text = entryGrid[indexPath.row].name
        addEntrantCell.entrantCompanyTextField.text = entryGrid[indexPath.row].company
        return addEntrantCell
    } else {
        let entrantCell = entrantsTable.dequeueReusableCell(withIdentifier: 
Global.bodyCellIdentifier,for: indexPath) as! EntrantCell
        entrantCell.delegate? = self
        entrantCell.nameLabel.text = entryGrid[indexPath.row].name
        entrantCell.companyLabel.text = entryGrid[indexPath.row].company
        return entrantCell
    }
}
}

extension UITableView {
func returnIndexPath(cell: UITableViewCell) -> IndexPath?{
    guard let indexPath = self.indexPath(for: cell) else {
        return nil
    }
    return indexPath                                       // This is supposed to help
}
}

自定义单元格:

import UIKit

class EntrantCell: UITableViewCell {

@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var companyLabel: UILabel!
@IBOutlet weak var inButton: UIButton!
@IBOutlet weak var outButton: UIButton!
@IBOutlet weak var inOutLabel: UILabel!

var delegate: InOutDelegate?
var buttonAction: ((_ sender: AnyObject) -> Int)?

override func awakeFromNib() {
    super.awakeFromNib()
    
    inButton.layer.cornerRadius = 10.0
    outButton.layer.cornerRadius = 10.0
    
    if Global.uiMode == true {
        overrideUserInterfaceStyle = .light
    } else {
        overrideUserInterfaceStyle = .dark
    }
}

// Attempt CHANGE

@IBAction func inButton(_ sender: UIButton) {
    delegate?.markIN(cell: self)
    print("in button pressed")            // Print statement fires
}

@IBAction func outButton(_ sender: UIButton) {
    delegate?.markOUT(cell: self)
}

override func setSelected(_ selected: Bool,animated: Bool) {
    super.setSelected(selected,animated: animated)
}
}

解决方法

您通过添加 ?在entrantCell.delegate? = self。这是有效的语法,因此编译器不会抱怨,但您不会得到想要的结果。你真的想要entrantCell.delegate = self

您的代码有条件地解包 delegate 并且由于该属性最初是 nil,因此不会进行任何赋值。实际上,您的代码表示如果 entrantCell.delegate 不是 nil,请将 self 分配给它。

如果没有 ?,将无条件地进行赋值。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。