skip to Main Content

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.

3

Answers


  1. Chosen as BEST ANSWER

    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)
    

  2. 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) }
        }
    }
    
    Login or Signup to reply.
  3. I use below way, it work for me. Maybe good idea, maybe bad idea. If you think bad solution please comment to answer.

    var disposeBag = DisposeBag()
    var selectedIndex = PublishSubject<Int>()
    

    We’ve listen click events here. We update the selectedIndex for clicked cell.

    self.myCollectionView.rx.itemSelected.subscribe(onNext: { indexPath in
    
                    self.selectedIndex.onNext(indexPath.row)           
    
            }).disposed(by: self.disposeBag)
    

    Here, we fill the collectionView. We adjust the colors according to the selectedIndex.

    Observable.of(myData)
               .bind(to: self.myCollectionView.rx.items(
                        cellIdentifier: MyCollectionViewCell.cellIdentifier,
                        cellType: MyCollectionViewCell.self)) { index, data, cell in
                            
                            self.selectedIndex.subscribe(onNext: { value in
    
                                if value == index {
                                    cell.contentView.backgroundColor = .red
                                } else {
                                    cell.contentView.backgroundColor = .blue
                                }
    
                            }).disposed(by: self.disposeBag)
               
                       }.disposed(by: self.disposeBag)
            
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search