【问题标题】:Test content of a custom TableViewCell测试自定义 TableViewCell 的内容
【发布时间】:2016-04-20 00:13:57
【问题描述】:

我正在使用 Swift 2 构建一个 iOS 应用程序,该应用程序使用自定义表格视图单元格、附加标签、图像视图等(我们将类称为 CustomTableViewCell)。我已经为每个子视图建立了类故事板连接,并为单元格分配了一个标识符。我已经模拟了数据并尝试运行应用程序以检查单元格是否正确映射,并且看起来没问题。

问题是我不能将出队的单元格视为CustomTableViewCell 来测试其属性的值。当我向下转换从tableView(tableView, cellForRowAtIndexPath: indexPath) 返回的单元格时,所有自定义属性值都变成nil,我的测试失败了。

这是我的代码:

MyViewControllerTests.swift

  func testShouldConfigureTableViewCellToDisplayNotification() {
    // Given
    sut.tableView = TableViewSpy()

    let items = [ <some items to display> ]
    sut.displayedItems = items

    // When
    let indexPath = NSIndexPath(forRow: 0, inSection: 0)
    let cell = viewController.tableView(viewController.tableView, cellForRowAtIndexPath: indexPath) as! CustomTableViewCell

    // Then
    XCTAssertEqual(cell.detailLabel?.text, "foo", "A properly configured table view cell should display the notification detail")
    XCTAssertEqual(cell.titleLabel?.text, "Bar", "A properly configured table view cell should display the notification title")
    XCTAssertEqual(cell.dateLabel?.text, "15/04/2016", "A properly configured table view cell should display the notification date")
  }

MyViewController.swift

  override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cellIdentifier = "CustomTableViewCell"
    let displayedItem = displayedItems[indexPath.row]
    var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? CustomTableViewCell
    if cell == nil {
      cell = CustomTableViewCell(style: .Value1, reuseIdentifier: cellIdentifier)
    }
    cell!.dateLabel?.text = displayedItem.date
    cell!.detailLabel?.text = displayedItem.detail
    cell!.titleLabel?.text = displayedItem.title
    return cell!
  }

CustomTableViewCell.swift

class CustomTableViewCell: UITableViewCell {
  // MARK: Properties
  @IBOutlet weak var dateLabel: UILabel!
  @IBOutlet weak var detailLabel: UILabel!
  @IBOutlet weak var titleLabel: UILabel!  

  override func awakeFromNib() {
    super.awakeFromNib()
      // Initialization code
  }

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

      // Configure the view for the selected state
  }

}

【问题讨论】:

    标签: ios swift uitableview


    【解决方案1】:

    尝试替换

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cellIdentifier = "CustomTableViewCell"
        let displayedItem = displayedItems[indexPath.row]
        var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as? CustomTableViewCell
        if cell == nil {
          cell = CustomTableViewCell(style: .Value1, reuseIdentifier: cellIdentifier)
        }
        cell!.dateLabel?.text = displayedItem.date
        cell!.detailLabel?.text = displayedItem.detail
        cell!.titleLabel?.text = displayedItem.title
        return cell!
      }
    

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cellIdentifier = "CustomTableViewCell"
        let displayedItem = displayedItems[indexPath.row]
        var cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier) as! CustomTableViewCell
        cell.dateLabel.text = displayedItem.date
        cell.detailLabel.text = displayedItem.detail
        cell.titleLabel.text = displayedItem.title
        return cell
      }
    

    如果您已将您的单元正确连接到情节提要中,那么这应该可以工作。否则,请检查您是否为您的单元正确分配了所有 IBOutlets。

    如果有问题,请检查以下内容:

    1) 在情节提要中选择您的单元格。

    2) 在右栏中打开 Identity Inspector(顶部的第三个选项卡)。确保您的单元格的类设置为CustomTableViewCell

    3) 在属性检查器(第 4 个选项卡)中,确保单元格标识符拼写正确。

    4) 在 Connections 检查器(最后一个选项卡)中,分配您定义的单元格的所有 IBOutlets。

    【讨论】:

    • 这使得 XCode 抛出一些构建错误:Cannot force unwrap value of non optional type "CustomTableViewCell",因为我在单元格出列时解开了它。当我从属性绑定中删除所有这些展开时,运行测试时出现致命错误:"unexpectedly found nil while unwrapping an Optional value"
    • 我的错!检查更新答案。问题在于“细胞!”的使用。单元格出队后:)
    • 这意味着您没有正确指定情节提要中的单元格。我现在将通过提供您需要检查的其他内容来更新我的答案
    • 我尝试重新分配网点,查找标识符中的拼写错误并将 CustomTableViewCell 类重新分配给我的单元格,但我不断收到展开可选错误。一个重要的细节是,只有当我尝试使用来自 cellForRow:atIndexPath 的单元格作为 CustomTableViewCell 进行单元测试时,我才会遇到这个问题,但是当我运行应用程序时,tge 值被正确映射
    【解决方案2】:

    从您的代码示例看来,您没有注册您的单元格以供重复使用。

    tableView.registerClass(CustomTableViewCell.self, forCellReuseIdentifier: "CustomTableViewCell")
    

    【讨论】:

    • 据我所知,如果我不使用情节提要进行单元类映射,我应该注册该类。这些技术是互补的吗?
    • 哦,对不起。你说的对。如果您使用原型单元,则不需要使用此代码。在这种情况下,确保您在 IB 中添加了正确的单元格标识符就足够了。此外,通常您需要使用此方法获取 UITableView 单元格 let cell = tableView.cellForRowAtIndexPath(indexPath) 但是您直接调用委托方法,如果您的表格未显示,则该方法可以返回空单元格。我只能建议尝试在 UITableView 委托方法中设置断点以了解发生了什么错误。或者使用您的 VC 代码发布示例项目。
    • 我已经尝试了您指出的内容,并得出结论,当我尝试向下转换 cellForRow:atIndexPath 的结果时,我的测试失败了。
    猜你喜欢
    • 1970-01-01
    • 2019-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-04
    • 2020-02-19
    • 1970-01-01
    相关资源
    最近更新 更多