ios - Swift 协议委托未在 VC 中触发
问题描述
在这里学习协议和代表,但我无法让这个场景发挥作用。我在自定义 tableView 单元中有两个按钮。我在每个按钮块中都有一个协议方法。当我按下按钮时,打印语句会触发,指示按钮工作,但 VC 内的协议不会触发。
本质上,我试图在每次按下按钮时获取 indexPath.row 。但它们都需要分开,我不想使用按钮标签。
我尝试了以下方法:
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, bundle: nil), 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
,因此不会进行任何分配。实际上,您的代码说If entrantCell.delegate
is not nil
,分配self
给它。
如果没有?
,则无条件地进行分配。
推荐阅读
- java - 使用叠加层时如何使按钮可点击
- python - 不同 x 的 matrix[x] 表示什么?
- c# - 将文本对齐到三列
- codeigniter - Codeigniter 按今天的价格和字段查询顶级商店
- javascript - 嵌套 json 对象中数组过滤器的使用
- c# - 使用来自 IFormFile 的 Stream 创建新的 ExcelPackage 不起作用
- c# - ASP.NET Core 2.2 为每个其他控制器返回 404
- php - 库存申请不会显示结果
- azure - 适用于 API 的 Azure AD B2C 登录和使用 API 唱歌(不是 html 页面)
- sql - 如何使用事务 sql 自动更改查询中的日期