【问题标题】:Swift 2.1 - IBOutlet property is nil in custom UITableViewCell classSwift 2.1 - 自定义 UITableViewCell 类中的 IBOutlet 属性为零
【发布时间】:2016-04-01 00:23:26
【问题描述】:

我相信创建自定义类来配置表格单元格是 iOS 开发的标准做法。我也将这种做法应用于我的应用程序,但我遇到了一些问题。

我有两个表格视图 - 每个 ViewController 一个 - 它们的单元格使用相同的自定义单元格类。

CustomCellClass

import UIKit

class RecipeCategoryCell: UITableViewCell {

    @IBOutlet weak var recipeCategoryLabel: UILabel!
    @IBOutlet weak var chooseCategoryLabel: UILabel!

    //...

    func configureCell(recipe: Recipe) {
        let category = recipe.category as? RecipeCategory
        recipeCategoryLabel.text = category!.name
    }

    func configureNewCell(category: RecipeCategory) {
        recipeCategoryLabel.text = category.name
    }

    // re-configure receiver's viewcontroller cell with selected category value
    func configureSelectedCategoryCell(selectedCategory: String) {        
        recipeCategoryLabel.text = selectedCategory
    }

    // configure all available category names in the sender's viewcontroller
    func configureChooseCategoryCell(category: RecipeCategory) {
        chooseCategoryLabel.text = category.name
    }
}

@IBOutlet weak var recipeCategoryLabel: UILabel! 属于接收者 viewController,@IBOutlet weak var chooseCategoryLabel: UILabel! 属于发送者 viewController

我在recipeCategoryLabel.text = selectedCategory 这一行的第三个函数有一个问题,Xcode

致命错误:在展开 Optional 时意外发现 nil 价值

我在使用相同 IBOutlet recipeCategoryLabel 的其他函数上没有这个问题,但只有函数 configureSelectedCategoryCell() 使用选定的类别值重新配置接收器 ViewController 单元格。 所以我可以肯定地说,这不是故事板的连接问题。

我想这是因为在多个地方使用了相同的 IBOutlet 属性。但问题是,我必须使用相同的属性,这样我才能设置默认值、更新选定的值、在同一个标​​签上设置以前持久的值。

我不知道我的解释是否足够清楚,但基本上我无法将接收者ViewController 的表格单元格标签设置为从发送者ViewController 传递的选定类别值。

更新

configureSelectedCategoryCell()在接收者的ViewController扩展中被调用:

extension CreateRecipeVC: RecipeCategoryTableVCDelegate {

func categoryController(controller: RecipeCategoryTableVC, didSelectCategory category: String) {

    selectedCategory = category

    self.navigationController?.popViewControllerAnimated(true)

    let cell = RecipeCategoryCell()
    cell.configureSelectedCategoryCell(selectedCategory)

}

}

【问题讨论】:

  • 你确定你 selectedCategory 不是一个 nil 对象吗?
  • 您是否可能在组件加载并连接到 IBOutlet 之前调用此函数?
  • 您何时调用configureSelectedCategoryCell 以及使用哪些机制(NSNotification、直接调用等)?
  • 请查看更新图片。它使用正确的字符串打印 selectedCategory,在控制台中显示“Drink”。
  • 这看起来很可疑:let cell = RecipeCategoryCell()。为什么不调用 dequeueReusableCellWithIdentifier?见developer.apple.com/library/ios/documentation/UIKit/Reference/…

标签: ios xcode swift uitableview


【解决方案1】:

当您尝试在configureSelectedCategoryCell 中访问它们时,单元格的出口并未实例化。

据我了解,单元格是在 Interface Builder 中设计的,因此单元格对象 cell 的出口缺少对 Interface Builder 中控件的引用。

选择一个类别后,您应该

  1. 更新 tableView 的数据源
  2. 重新加载 tableView 的项目

类似这样的:

func categoryController(controller: RecipeCategoryTableVC, didSelectCategory category: String) {

    selectedCategory = category
    self.navigationController?.popViewControllerAnimated(true)

    tableViewDataSource[selectedItemIndex].selectedCategory = selectedCategory
    tableView.reloadData()
}

然后在表格视图中数据源委托:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

   let cell = tableView.dequeueReusableCellWithIdentifier("YourCellIdentifer") as! RecipeCategoryCell
   cell.configureSelectedCategoryCell(tableViewDataSource[indexPath.row].selectedCategory)
   return cell
}

旁注:

将一个 IBOutlet 连接到情节提要中的多个控件是合法的。

作为预防措施,我建议删除 configureCell 中可选的强制展开,例如

func configureCell(recipe: Recipe) {
    if let category = recipe.category as? RecipeCategory {
       recipeCategoryLabel.text = category.name
    }
}

【讨论】:

  • 感谢您的意见。我不太了解数据源更新部分tableViewDataSource[selectedItemIndex].selectedCategory = selectedCategory 我可以从发件人那里获得所选项目的索引,但当我已经知道 selectedCategory 持有什么时,我不确定为什么需要此分配。
  • 你能描述一下你的应用程序关于两个表视图的逻辑吗?我知道一个表格视图用于选择食谱类别。另一个表视图是做什么用的,两个表视图中的哪一个导致异常?
  • 这是我之前的问题,它解释了两个表视图背后的逻辑。接收方抛出异常 - CreateRecipeViewController stackoverflow.com/questions/36322178/…
  • @SeongLee 谢谢。 CreateRecipeVC 中的表格视图是静态的还是动态的,即您是在 CreateRecipeVC 中提供数据源还是在 Interface Builder 中设计了固定的单元格?
  • 虽然我只有一个单元格,但我在 CreateRecipeVC 中使用了动态单元格,因为在呈现这个单元格时会有各种情况。顺便说一句,我按照您的指导进行了这项工作! dequeueReusableCellWithIdentifier("YourCellIdentifer") 是关键。我将更新我的问题以显示我对数据做了什么。
猜你喜欢
  • 2016-01-22
  • 1970-01-01
  • 2015-04-07
  • 2018-12-06
  • 1970-01-01
  • 2012-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多