Home > Blockchain >  How do I change background color on cells that are not selected using rx swift?
How do I change background color on cells that are not selected using rx swift?

Time:05-17

In order to set a color on a selected cell I do the following:

armSystemTableView.rx.itemSelected.subscribe(onNext: { indexPath in
    let cell = self.armSystemTableView.cellForRow(at: indexPath) as? TechnicianArmSystemTableViewCell
                
    cell?.backgroundColor = .green
                
}).disposed(by: disposeBag)

While this works, it doesn't remove the selection color on all other cells, meaning that every cell I click will turn green. How do I restore all the unselected cells to their original color?

I also tried using override func setSelected(_ selected: Bool, animated: Bool) but that didn't work in conjunction with setting a default selected cell as I think setSelected overrides the default:

armSystemViewModel.content.bind(to: armSystemTableView.rx.items(cellIdentifier: TechnicianArmSystemTableViewCell.identifier, cellType: TechnicianArmSystemTableViewCell.self)) {
    row, data, cell in
        cell.viewModel = data
        if row == cell.viewModel?.parameter.value {
            cell.setSelected(true, animated: false)
        } else {
            cell.setSelected(false, animated: false)
        }
}.disposed(by: disposeBag)

Here I set the default selected cell. But it won't work and I think the reason is that it's overriden by setSelected:

 override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)
    setSelectedColors(selected: selected)
}
    
func setSelectedColors(selected: Bool) {
    if selected {
        contentView.backgroundColor = .green
    } else {
        contentView.backgroundColor = .red
    }
}

There should be a cell marked greed per default, but there isn't. If I remove setSelected and change to setting the background color it will work with the default selected cell:

...
if row == cell.viewModel?.parameter.value {
    cell.backgroundColor = .green
} else {
    cell.backgroundColor = .red
}

So how do I make this happen? Seems simple enough: one cell should be marked green when you enter the view. When selecting any other cell that cell will instead become green and any other cell will become red.

CodePudding user response:

I found a way. Loop all visible cells and change the color on each, then set the color on a specific cell. Not the prettiest I suppose, but it does work:

armSystemTableView.rx.itemSelected.subscribe(onNext: { indexPath in
    self.armSystemTableView.visibleCells.forEach { $0.backgroundColor = .tableviewBackgroundColor }
                
    let cell = self.armSystemTableView.cellForRow(at: indexPath) as? TechnicianArmSystemTableViewCell
    cell?.backgroundColor = .selectedCellColor
}).disposed(by: disposeBag)

CodePudding user response:

Here's a more Rx'ish way to do it:

items
    .bind(to: tableView.rx.items) { (tableView, row, element) in
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
        cell.textLabel?.text = "\(element) @ row \(row)"
        cell.rx.setSelected
            .subscribe(onNext: { [contentView = cell.contentView] selected, animated in
                contentView.backgroundColor = selected ? .green : .white
            })
            .disposed(by: cell.disposeBag)
        return cell
    }
    .disposed(by: disposeBag)

You will need to define this to get the above to work:

extension Reactive where Base: UITableViewCell {
    var setSelected: Observable<(selected: Bool, animated: Bool)> {
        base.rx.methodInvoked(#selector(UITableViewCell.setSelected(_:animated:)))
            .map { (selected: $0[0] as! Bool, animated: $0[1] as! Bool) }
    }
}
  • Related