1

I have one request for any of you. I want to create collectionview/tableview which will have user inputs in cells. Mixture of values from those inputs would represent state. I want to observe that state and if some conditions are met, I want to recreate all cells. I have created very simple app, where I demonstrate how i tried to implement it, but I’m getting reentrancy warning and I would love to find out your ideas/best practicies for this. Here is the repo you can checkout.

https://github.com/beretis/CollectionViewTest

PS: Im using RxData sources, and I would love to know exactly what is causing this reentrancy (I have my idea)

beretis
  • 899
  • 1
  • 9
  • 24

1 Answers1

0

I sent a pull request your way.

The key to answer this question is to have two Observables in your view model. One that represents the programatic state of each cell (the stuff that the user doesn't input) and one that represents the user input state of each cell. You connect the data from these two Observables using some sort of ID value (I use UUID.) So for your specific example, the view model for the collection should look like this:

typealias CellID = UUID

struct StaticCellState {
    let id: CellID
    let placeholder: String
}

struct CollectionViewModel {
    let cells: Observable<[StaticCellState]>
    let cellStates: Observable<[CellID: String]>
}

The cells observable contains the placeholder and cell ID. This is the data that the cell uses when it is configured and doesn't change for the life of that configuration (It might change if the cell is reused.) It is only updated if you want to add/remove a cell or change the placeholder value of a particular cell.

The cellStates observable contains the latest user input values and is updated every time the user types into one of the cells' text fields.

Then you configure your cells by passing in the information for that cell from both observables:

let dataSource = RxCollectionViewSectionedReloadDataSource<SectionOfCustomData>(
    configureCell: { dataSource, collectionView, indexPath, item in
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as? SomeCell else { return UICollectionViewCell() }
        let output = cell.configure(with: item, initial: viewModel.cellStates.map { $0[item.id]! })
        output
            .bind(to: itemEdit)
            .disposed(by: cell.disposeBag)
        return cell
})
Daniel T.
  • 32,821
  • 6
  • 50
  • 72
  • Hi, first of all thank you for your time and effort, people like you are immerse help. Sorry for late response, I'm on a vacation right now. I will check your PR and discuss. – beretis May 21 '19 at 08:15