我在从与以编程方式创建的 TableView 关联的 TableView 标头调用 segue 时遇到问题。作为权宜之计,我使用单例保存了对主 UITableViewController 的对象引用,但这不是理想的解决方案。
我的 TableViewController 有多个部分,每个部分有 1 行或 2 行,具体取决于是否选择了顶级部分行。第二行有效地用于扩展所选行上显示的内容。
第二行包含一个包含滑块菜单的自定义单元格,并且根据所选的菜单项,容器视图中显示 5 个子视图中的 1 个。
其中一个子视图包含一个以编程方式生成的 TableView,它具有自己的自定义标题和自定义单元格。此单元格包含一个标题和一个嵌入式按钮。当在标题中按下按钮时,我想转到另一个导航控制器,但是,我的问题是我无法正确初始化委托来访问主 TableViewController。
它变得有点复杂,因为自定义单元格创建自己的 TableView 并处理通常在主控制器上使用重写的操作的自己的功能,例如didSelectRowAt、numberOfRowsInSelection、headerForRowAt 等
class pendingNotificationCustomCell: UITableViewCell, UITableViewDataSource, UITableViewDelegate {
var dataSample:[String] = ["Row 1,"Row 2", "Row 3"]
var PendingTableView: UITableView?
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func awakeFromNib() {
print("##### awakeFromNib")
super.awakeFromNib()
// Initialization code
setUpTable()
}
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style , reuseIdentifier: reuseIdentifier)
setUpTable()
}
func setUpTable() {
PendingTableView = UITableView(frame: CGRect.init(), style:UITableView.Style.plain)
PendingTableView?.delegate = self
PendingTableView?.dataSource = self
PendingTableView?.register(MyCell.self, forCellReuseIdentifier: "pendingnotificationsCellID")
PendingTableView?.register(PendingNotificationsHeader.self, forHeaderFooterViewReuseIdentifier: "pendingHeaderID")
PendingTableView?.sectionHeaderHeight = 40
PendingTableView?.allowsSelection = true
PendingTableView?.allowsMultipleSelection = false
self.addSubview(PendingTableView!)
}
我可以轻松地设置协议和关联的委托来访问管理主要 TableView 自定义单元格的控制器上的功能。然而,由于有问题的自定义单元不继承与执行 segues 相关的功能,我需要访问主控制器上的功能。
我已经对此进行了很多实验,但除了 Singleton hack 之外还没有想出一个可行的解决方案。
let pendingCell = pendingNotificationCustomCell()
pendingCell.delegate4 = mStats.mainController
当我尝试为 delegate4 分配一个引用主 TableViewController 的初始化插座时,它到达那里时始终具有“nil”值。即使当我在类中为它分配单例值时,它也会生成第二个 表视图。注释掉的行失败,而使用 mStats Singleton 调用方法工作正常。
//delegate4.callSegueFromCell2(myData: myData)
mStats.mainController?.callSegueFromCell2(myData: myData)
上面注释掉的delegate4,在cell header classes中设置如下:
protocol MyCustomCellDelegator3 {
func callSegueFromCell2(myData dataobject: AnyObject)
}
class PendingNotificationsHeader: UITableViewHeaderFooterView {
var delegate4:MyCustomCellDelegator3!
var MainTableViewController: MainTableViewController?
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
setupViews()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
let nameLabel: UILabel = {
let label = UILabel()
label.text = "Pending"
label.font = UIFont.systemFont(ofSize: 17)
label.textColor = .white
return label
}()
let priceAlertButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Add new", for: .normal)
button.titleLabel?.font = UIFont (name: "Helvetica", size: 15)
button.setTitleColor(.white, for: .normal)
button.addTarget(self,action: #selector(createNewPriceAlertButtonPressed), for: .touchUpInside)
return button
}()
@IBAction func createNewPriceAlertButtonPressed(_ sender: Any) {
print ("##### New Price Alert Label Pressed")
// Get the view
var mydata = self
//delegate4.callSegueFromCell2(myData: myData)
mStats.mainController?.callSegueFromCell2(myData: myData)
}
感谢任何指导。
let pendingCell = pendingNotificationCustomCell()
看起来很奇怪。
你应该在
tableView(cellForRow:at:)
UITableViewDataSource 方法中设置你的单元格。
与在单元格上设置委托而不将其传递到节标题有关的问题。我最终解决了如下问题:
我在 MainViewController 中实现了一个名为 API_Segue_01 的函数和委托
final class MainTableViewController: UITableViewController, API_Segue_01 {
func API_Segue_01(myData dataobject: AnyObject) {
navigationItem.backBarButtonItem = UIBarButtonItem(title: "Back", style: .plain, target: nil, action: nil)
self.performSegue(withIdentifier: "showCreateNotificationsViewController", sender:dataobject )
}
/// Rest of class code
/// ...
在自定义单元格中,我创建了一个标头原型来引用外部函数:
protocol API_Segue_01 {
func API_Segue_01(myData dataobject: AnyObject)
}
我定义了一个 var 来保存对自定义单元格和关联标题中 MainTableViewController 的引用
class pendingNotificationCustomCell: UITableViewCell, UITableViewDataSource, UITableViewDelegate {
var funcCallTo: API_Segue_01!
/// Rest of class code
/// ...
class PendingNotificationsHeader: UITableViewHeaderFooterView {
var funcCallTo:API_Segue_01!
/// Rest of class code
/// ...
创建自定义单元格的实例时,我提供了对 MainTableViewController 的引用
pendingCell.funcCallTo = mainTableViewController
由于操作按钮位于单元格标题中,因此我将引用传递给 viewForHeaderInSection 中的 mainTableViewController,如下所示
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
print("##### viewForHeaderInSection")
let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: "pendingHeaderID") as! PendingNotificationsHeader
header.funcCallTo = self.funcCallTo
return header
}
然后我可以使用这个引用来调用 API_Segue_01 函数
@IBAction func createNewPriceAlertButtonPressed(_ sender: Any) {
print ("##### New Price Alert Label Pressed")
// Get the view
var mydata = self /
funcCallTo.API_Segue_01(myData: mydata)
}