带有自定义单元格的 UITableView 弹出窗口失败,单元格属性始终为零

Posted

技术标签:

【中文标题】带有自定义单元格的 UITableView 弹出窗口失败,单元格属性始终为零【英文标题】:UITableView popover with custom cell fails with cell attributes always nil 【发布时间】:2017-03-24 16:32:55 【问题描述】:

我正在尝试使用自定义单元格呈现 UITableView 弹出框,但我的单元格中的 UILabel 插座始终为零。我使用情节提要来创建弹出表视图和自定义单元格。一切似乎都正确连接,我的自定义单元格具有“单元格”标识符。弹出框显示正确,只是自定义单元格中的标签不会设置,因为它们是 nil。

我尝试使用 Apple 方法(请参阅下面的 buttonPressed 函数)和 UITableViewCell's attributes are nil when instantiating UITableView as a popover 中建议的 segue 方法来呈现弹出框,但都没有解决我的问题。

我的自定义 UITableViewCell 类有两个连接的标签和一个未连接的 int。所有故事板连接似乎都有效:

class PopoverTableCell : UITableViewCell 
   @IBOutlet var label1: UILabel!   // <== connected in storyboard
   @IBOutlet var label2: UILabel!   // <== connected in storyboard

   var int3 : Int? = nil

这是我从视图控制器(通过按钮推送)呈现它(Apple 的方法)的方式:

class ViewController: UIViewController 

   override func viewDidLoad() 
      super.viewDidLoad()
      // Do any additional setup after loading the view, typically from a nib.
   

   @IBAction func buttonPressed(_ sender: UIButton) 
      let popoverController = PopoverController()
      popoverController.modalPresentationStyle = UIModalPresentationStyle.popover
      popoverController.preferredContentSize = CGSize(width: 200, height: 300)

      present(popoverController, animated: true, completion: nil)

      let popoverPresentationController = popoverController.popoverPresentationController
      popoverPresentationController?.sourceView = sender
      popoverPresentationController?.sourceRect = CGRect(x: 0, y: 0, width: sender.frame.size.width, height: sender.frame.size.height)

   

   override func didReceiveMemoryWarning() 
      super.didReceiveMemoryWarning()
      // Dispose of any resources that can be recreated.
   


这成功地打开了弹出框,但是当我尝试在单元格中设置标签时,它失败了,因为标签始终为零。

class PopoverController : UITableViewController 

   override func viewDidLoad() 
      super.viewDidLoad()

      // it makes no difference if I set these or not - storyboard does it for me
      self.tableView.delegate = self
      self.tableView.dataSource = self

      // if I don't register, the cell fails to deque
      self.tableView.register(PopoverTableCell.self, forCellReuseIdentifier: "Cell")
   

   override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
      let cell = tableView.dequeueReusableCell(withIdentifier: "Cell") as! PopoverTableCell
      cell.backgroundColor = UIColor.yellow
      cell.label1?.text = "Label 1111"
      cell.label2?.text = "Label 2222"
      cell.int3 = 5555
      print("label1: \(cell.label1)")     // <== always nil
      print("label2: \(cell.label2)")     // <== always nil
      print("label3: \(cell.int3)")       // <== always Optional(5555) which is correct
      return cell
   

   override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
      return 4
   


我在 cellForRowAt 基金的 return 语句上放了一个断点,我在调试器中得到了这个:

Debugger Image

无论我做什么,label1 和 label2 出口始终为零,但 int3(不是出口)似乎工作得很好。

【问题讨论】:

这些原型单元格是否在情节提要的场景中?您需要在情节提要中设置单元格的标识符,而不是在代码中注册单元格。您无法在情节提要中创建的代码中注册单元格。 【参考方案1】:

我认为此评论中描述的问题:

  // if I don't register, the cell fails to deque

nil 出口是同一问题的症状。

如果您在情节提要中创建插座,它们将无法通过默认的 init() 方法正确初始化,这是您在使用 PopoverController() 创建视图控制器时使用的方法。

尝试在情节提要中为您的视图控制器提供一个标识符:

然后像这样实例化它:

  let popoverController = storyboard?.instantiateViewController(withIdentifier: "MyViewController") as! PopoverController

在这种情况下,单元格应该从情节提要中提取(准确地说,它通过init?(coder aDecoder: NSCoder) 方法而不是init()),因此它们的出口不会为零。如果您以这种方式实例化视图控制器,您也不需要注册单元格。

【讨论】:

【参考方案2】:

您不需要注册单元格,因为您在情节提要中创建了单元格。我还想解释一下错误:错误 Int 工作正常但 UILabel 为零,原因是未加载 UILabel(任何视图)。

【讨论】:

谢谢,但为什么没有加载 UILabel?

以上是关于带有自定义单元格的 UITableView 弹出窗口失败,单元格属性始终为零的主要内容,如果未能解决你的问题,请参考以下文章

带有包含自定义单元格的 UITableView 的 UISearchBar => 空白单元格

带有单个自定义单元格的 UITableView? (苹果手机)

带有自定义单元格的 ViewController 内的 UITableView 没有情节提要

iOS - 带有自定义单元格的可点击 UITableView

带有Swift的多个自定义单元格的UITableview

带有多个自定义单元格的“UITableView 无法从其数据源获取单元格”