为什么我的最后一个细胞失去了它的背景颜色及其内容

时间:2017-09-07 05:25:19

标签: swift uitableview

这是我的代码,我无法理解为什么我丢失了我的最后一个单元格功能:

extension ItemsViewController {

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)

        let item = itemStore.allItems[indexPath.section]

        if indexPath.row == item.count {
            let lastCell = UITableViewCell(style: .default, reuseIdentifier: "lastCell")
            lastCell.backgroundColor = #colorLiteral(red: 0.9568627477, green: 0.6588235497, blue: 0.5450980663, alpha: 1)
            lastCell.textLabel?.text = "No more Items"
            return lastCell
        }

        cell.textLabel?.text = item[indexPath.row].name
        cell.detailTextLabel?.text = "$\(item[indexPath.row].valueInDollars)"


        return cell
    }

    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
        return section == 0 ? "below 50" : "above 50"
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return itemStore.allItems[section].count + 1
    }

    override func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return indexPath.row == itemStore.allItems[indexPath.section].count - 1 ? 44 : 60
    }
}

如果我不使用最后一种方法(heightForRowAt),那么一切正常。但是,如果我使用它,我会获得正确的单元格大小,但我会丢失最后一个单元格及其颜色的内容。

4 个答案:

答案 0 :(得分:1)

初看一眼,

if indexPath.row == item.count { 

我相信错误可能就在那里。打印出每个的计数。 indexPath可能会少1。因此,最后的内容不会被设置。

Haven还没有运行代码。

答案 1 :(得分:1)

我有一个正确的答案。使用以下cellForRow实现而不是您的实现:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    // Do not dequeue the cell here, because two lines below you might decide that you do not want to use it
    // let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)

    let item = itemStore.allItems[indexPath.section]

    if indexPath.row == item.count {
        let lastCell = UITableViewCell(style: .default, reuseIdentifier: "lastCell")
        lastCell.backgroundColor = #colorLiteral(red: 0.9568627477, green: 0.6588235497, blue: 0.5450980663, alpha: 1)
        lastCell.textLabel?.text = "No more Items"
        return lastCell
    }

    // Dequeue reusable cell here, when you know you are going to use it:
    let cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell", for: indexPath)

    cell.textLabel?.text = item[indexPath.row].name
    cell.detailTextLabel?.text = "$\(item[indexPath.row].valueInDollars)"


    return cell
}

唯一的区别是,只有当您知道要使用出列的单元格时,才会在测试后将可重复使用的单元格出列。 Tableview显然希望你返回那个单元格,如果你已经将它出列了。它可能使用它来使渲染更有效,它甚至在你真正返回它之前呈现单元格(并且只修改你稍后改变的内容),因此看起来你最后一个单元格的代码不起作用(它可以工作,但之前你返回你的最后一个单元格,表格呈现出队的单元格。

故事的寓意:如果您为给定的indexPath出列可重用单元格,则tableView希望您真正返回它

官方documentation

  

如果现有单元格可用,则此方法会出现,或者根据先前注册的类或nib文件创建新单元格并将其添加到表格中。

要将指定indexPath的单元格出列,您已将其添加到表中。这意味着,如果您使用dequeueReusableCell(withIdentifier:)而不是dequeueReusableCell(withIdentifier:for:),则调用顺序无关紧要,因为dequeueReusableCell(withIdentifier:)不会将其添加到表中。但是,我仍然宁愿选择我的解决方案,只有在需要时才将其出列。

答案 2 :(得分:0)

我认为您需要注册lastCell,然后使用dequeueReusableCell加载单元格,这里是代码:

if indexPath.row == item.count {
        let lastCell = UITableViewCell(style: .default, reuseIdentifier: "lastCell")
        lastCell.backgroundColor = #colorLiteral(red: 0.9568627477, green: 0.6588235497, blue: 0.5450980663, alpha: 1)
        lastCell.textLabel?.text = "No more Items"
        return lastCell
}

替换为:

tableView.register(UITableViewCell.self, forCellReuseIdentifier:"lastCell")

if indexPath.row == item.count {
        let lastCell = tableView.dequeueReusableCell(withIdentifier: "lastCell", for: indexPath)
        lastCell.backgroundColor = #colorLiteral(red: 0.9568627477, green: 0.6588235497, blue: 0.5450980663, alpha: 1)
        lastCell.textLabel?.text = "No more Items"
        return lastCell
}

答案 3 :(得分:0)

试试这个:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {

    if indexPath.row == item.count {
        // Place your desired color for the last cell.
        cell.backgroundColor = UIColor.red
    }
    else {
        // This should be the normal cell background color.
        cell.backgroundColor = UIColor.white
    }
}

根据您的要求,单个可重复使用的单元就足够了。假设您已经注册了一个带有标识符" MyTableViewCellIdentifier"的单元格。 见下面的方法:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "MyTableViewCellIdentifier", for: indexPath)

    let item = itemStore.allItems[indexPath.section]

    if indexPath.row == item.count {
        cell.textLabel?.text = "No more Items"
        cell.detailTextLabel?.text = nil
    }
    else {
        cell.textLabel?.text = item[indexPath.row].name

        let valueInDollars = item[indexPath.row].valueInDollars
        cell.detailTextLabel?.text = $ + valueInDollars
    }

    return cell
}

(斯威夫特3)