更改视图外单元格的背景颜色

Posted

技术标签:

【中文标题】更改视图外单元格的背景颜色【英文标题】:Changing Background color on Cell outside of view 【发布时间】:2017-05-31 14:48:40 【问题描述】:

我最近发现我的代码有一个错误,在尽我所能解决它之后,我能够弄清楚我认为正在发生的事情。在我的应用程序中,如果用户选择该单元格,我会更改背景颜色,这样您就可以选择多个单元格。但是,如果选择了第一个单元格,它将取消选择(更改背景颜色)所有其他单元格。但事实证明我收到以下错误:

致命错误:在展开可选值时意外发现 nil

当我尝试更改屏幕上不可见的单元格的背景颜色时。我假设这是因为只有可见单元格被加载到内存中,而所有其他单元格只有在它们再次可见时才会被加载。

那么我将如何手动加载一个我知道 IndexPath 但也知道它在视图之外的单元格。另外,有没有办法知道 IndexPath 处的单元格是否已加载?

这是我当前的代码。

func selectAnyList(tableView: UITableView) 

    let sections = frc!.sections!
    let currentSection = sections[0]
    let numRows = currentSection.numberOfObjects

    for i in 0...(numRows - 1) 
        let indexPath = IndexPath(row: i, section: 0)

        let cell = tableView.cellForRow(at: indexPath) as! ItemListTVCell   //This is where the error happens if the cell is not visible
        if (i == 0) 
            cell.backgroundColor = UIColor.activeAqua.withAlphaComponent(0.85)
         else 
            cell.backgroundColor = UIColor.white.withAlphaComponent(0.85)
        
    

编辑:添加单元格的加载方式

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

    let list: Ent_Lists = frc!.object(at: indexPath)
    let cell = tableView.dequeueReusableCell(withIdentifier: "itemListCell", for: indexPath) as! ItemListTVCell

    if (list == Ent_Lists.anyList) 
        self.anyCell = cell
    

    cell.listName.text = list.name
    cell.listImage.image = list.image!.uiImage

    if ((indexPath as NSIndexPath).row != 0 && listSet!.contains(list)) 
        numLists += 1
    

    return cell

Edit2:在 Coredata 中添加了 Ent_List 的图像。

【问题讨论】:

您的列表中是否有一些模型的数组?如果是,请添加一个名为 bgColor 的额外属性,并对其进行更新。 我还是个很绿色的程序员,我不确定我是否理解你的建议。 你能展示一下Ent_Lists 的样子吗? 添加了来自 Coredata 的 Ent_Lists 的图像 您是否总是希望第一个单元格的背景颜色不同?或者它可以是任何单元格,其 bg 颜色应该与其他单元格不同? 【参考方案1】:

我创建了一个小示例文件,您可以在其中动态设置背景颜色,并且每次您选择的背景颜色都会有不同的背景颜色。

import UIKit

// This is your core data entity
struct Entity 
    let title: String


// This is a basic viewModel, holding the selected property and the core data entity
class EntityViewModel 
    let entity: Entity
    // Set the selected property to false
    var selected: Bool = false

    init(entity: Entity) 
        self.entity = entity
    


class TableViewController: UIViewController 

    @IBOutlet weak var tableView: UITableView!
    lazy  fileprivate var entityViewModels: [EntityViewModel] = self.makeEntityViewModels(count: 20)

    override func viewDidLoad() 
        super.viewDidLoad()
        tableView.dataSource = self
        tableView.delegate = self

    


extension TableViewController: UITableViewDataSource 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
        return entityViewModels.count
    

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
        // Work with viewModels, instead of the CoreData entities directly
        let viewModel = entityViewModels[indexPath.row]
        // Set the title of the cell
        cell.textLabel?.text = viewModel.entity.title
        // Based on the selected property, set the background color
        cell.backgroundColor = viewModel.selected ? .black : .yellow
        return cell
    

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) 
        // Reset the selection for all viewModels
        entityViewModels.forEach  
            $0.selected = false
        

        // Get the viewModel at the right indexPath
        let viewModel = entityViewModels[indexPath.row]
        // Set its selected state to true
        viewModel.selected = true
        // Reload the tableView -> this will trigger `cellForRowAt`, and your background colors will be up to date
        self.tableView.reloadData()
    


extension TableViewController 
    // This is where you read up from core data
    private func makeEntities(count: Int) -> [Entity] 
        var entities: [Entity]  = []
        for index in 0..<count 
            entities.append(Entity(title: "\(index) Some title"))
        
        return entities
    
    // Just wrap the core data objects into viewModels
    func makeEntityViewModels(count: Int) -> [EntityViewModel] 
        let entities = makeEntities(count: count)
        var viewModels: [EntityViewModel] = []
        for (index, entity) in entities.enumerated() 
            let viewModel = EntityViewModel(entity: entity)
            // Intialy, set the first viewModel to selected
            if index == 0 
                viewModel.selected = true
            
            viewModels.append(viewModel)
        
        return viewModels
    

【讨论】:

谢谢,我试试看 @JasonBrady 我已经修改了makeEntityViewModels 函数,所以在设置viewModels时将选择第一项。 再次感谢您。我现在在上班,所以我今晚试试。

以上是关于更改视图外单元格的背景颜色的主要内容,如果未能解决你的问题,请参考以下文章

如何在listview android中仅更改第二个单元格的背景颜色

更改单元格的背景颜色

更改每个其他单元格的 UItableViewCell 背景颜色

iOS UITableView:更改表格的背景颜色会覆盖单元格的背景颜色

选中时更改 UICollectionView 单元格的背景和标签颜色

如何使用 WPF Toolkit Datagrid 更改单元格的背景颜色