ios tableView重用问题

时间:2017-08-08 06:00:28

标签: ios swift uitableview

我有一个音乐列表tableView,单元格上的数据来自音乐模型。我想在选择单元格时将2个标签的颜色从默认颜色白色更改为红色。    在音乐模型中有一个名为isSelected的属性,用于指示是否选择了单元格。所以我使用以下代码:

 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "MusicTableViewCell", for: indexPath) as! MusicTableViewCell
        cell.music = musics[indexPath.row]
        cell.numberLabel.text = String(indexPath.row + 1)

        if musics[indexPath.row].isSelected == false {
            cell.titleLabel.textColor = .white
            cell.artistLabel.textColor = .white
            cell.speakerImageView.isHidden = true
            cell.numberLabel.isHidden = false
        } else {
            cell.titleLabel.textColor = UIColor(r: 227, g: 0, b: 24)
            cell.artistLabel.textColor = UIColor(r: 227, g: 0, b: 24)
            cell.speakerImageView.isHidden = false
            cell.numberLabel.isHidden = true
            musics[indexPath.row].isSelected = true
        }

        return cell
    }



override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

            if lastSelectedIndexPath != nil  {
            let cell = tableView.cellForRow(at: lastSelectedIndexPath)! as! MusicTableViewCell
            cell.titleLabel.textColor = .white
            cell.artistLabel.textColor = .white
            cell.speakerImageView.isHidden = true
            cell.numberLabel.isHidden = false
            musics[lastSelectedIndexPath.row].isSelected = false
        }

        let cell = tableView.cellForRow(at: indexPath) as! MusicTableViewCell
        cell.titleLabel.textColor = UIColor(r: 227, g: 0, b: 24)
        cell.artistLabel.textColor = UIColor(r: 227, g: 0, b: 24)
        cell.speakerImageView.isHidden = false
        cell.numberLabel.isHidden = true

        lastSelectedIndexPath = indexPath as IndexPath
        currentMusicIndex = indexPath.row
        musics[currentMusicIndex].isSelected = true

            }
        }

我首先单击第二个单元格,然后将tableview滚动到底部,然后单击最后一个单元格,但应用程序将崩溃。日志是:在展开可选值时意外发现nil

screenshot

click the last cell

如何解决?感谢。

3 个答案:

答案 0 :(得分:1)

App课程中,只需覆盖MusicTableViewCell属性

即可
isSelected

现在,无论何时选择/取消选择您的单元格,此override var isSelected: Bool{ didSet{ if self.isSelected { self.titleLabel.textColor = .white self..artistLabel.textColor = .white self.speakerImageView.isHidden = true self.numberLabel.isHidden = false } else { self.titleLabel.textColor = UIColor(r: 227, g: 0, b: 24) self.artistLabel.textColor = UIColor(r: 227, g: 0, b: 24) self.speakerImageView.isHidden = false self.numberLabel.isHidden = true } } } 属性都会相应地自定义您的单元格。

修改

要保存选择的单元格,再次运行应用程序时,需要保留此数据。有多种方法可以在多个App会话之间保留数据。您可以使用:

  1. UserDefaults
  2. 核心数据
  3. 存档并将其保存在文件

答案 1 :(得分:1)

  
      
  1. 不要直接使用细胞
  2.   

覆盖MusicTableViewCell类中的setSelected函数

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

    if selected {
        self.titleLabel.textColor = UIColor(r: 227, g: 0, b: 24)
        self.artistLabel.textColor = UIColor(r: 227, g: 0, b: 24)
        self.speakerImageView.isHidden = false
        self.numberLabel.isHidden = true
    } else {
        self.titleLabel.textColor = .white
        self.artistLabel.textColor = .white
        self.speakerImageView.isHidden = true
        self.numberLabel.isHidden = false
    }
}
  
      
  1. 清除您的代码
  2.   

覆盖功能

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "MusicTableViewCell", for: indexPath) as! MusicTableViewCell

        return cell
    }

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
        let _cell = cell as! MusicTableViewCell

        _cell.music = musics[indexPath.row]
        _cell.numberLabel.text = String(indexPath.row + 1)
    }
  

您的选择将自动在MusicTableViewCell中设置。

如果你应该检测到这一点。

覆盖didSelectRowAt函数

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
      print("\(indexPath)")
}

答案 2 :(得分:0)

检查以下方法以更改选择颜色并取消选择

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

    cell.textLabel?.text = trainingCategories[indexPath.row]
    cell.textLabel?.textColor = UIColor.white


    return cell
}

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.cellForRow(at: indexPath as IndexPath)?.textLabel?.textColor = UIColor.red
}

func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
    tableView.cellForRow(at: indexPath as IndexPath)?.textLabel?.textColor = UIColor.white

}