Search code examples
swiftuitableviewrx-swiftreactivexmoya

RxCocoa extra argument in call


I am trying to attach data to a UITableView. I have download the project form here and am using the code where data is attached to the tableView: http://yannickloriot.com/2016/01/make-uitableview-reactive-with-rxswift/:

Firstly I have created the following variable:

let currentQuestion: Variable<Taxi?>   = Variable(nil)

I then try to do the following:

 currentQuestion
        .asObservable()
        .bindTo(tableView.rx_itemsWithCellIdentifier("ChoiceCell", cellType: ChoiceCell.self)) { (row, element, cell) in
            cell.choiceModel = element
        }
        .addDisposableTo(disposeBag)

But I am getting the following warning: 'Extra argument in call' on the line .bindTo. I have tried adding a new cell and get the same result. Not sure if it is relevant, but I have registered the cell.

I have read here that you can get this warning if the types of the arguments don't match: Swift - Extra Argument in call . However it looks like the arguments match fine.

I am new to Rx and was hope someone could help me understand what might be going wrong here. Thanks.

======

Edit

Here is my new code. I have tried rx_itemsWithCellIdentifier("ChoiceCell") alone and rx_itemsWithCellIdentifier("ChoiceCell", cellType: ChoiceCell.self):

let currentQuestion = Variable<[Taxi]>(taxis)

    currentQuestion.asObservable()
        .bindTo(tableView.rx_itemsWithCellIdentifier("ChoiceCell")) {(row, element, cell) in
        cell.choiceModel = element
        }.addDisposableTo(disposeBag)

Where I have used (taxis), it is an array of taxi items. See picture below:

enter image description here

Also once I have called .asObservable(), I have the following:

enter image description here

I managed to print these out by removing the line .bindTo. If I add that line back I get the same error as before.

IMPORTANT: I played around with code base from article I linked to earlier. If I remove from ChoiceCell I can replicate the same error:

//  var choiceModel: ChoiceModel? {
//    didSet {
//          layoutCell()
//    }
//  }

Solution

  • Thanks to Philip Laine answer above: https://stackoverflow.com/a/36536320/2126233

    That helped me see that I was making a mistake in regards to what I was observing. It helped me to see the problem I was having in my code.

    If you just want to bind to a normal tableViewCell then you need to use tableView.rx_itemsWithCellFactory:

    currentQuestion.asObservable()
            .bindTo(tableView.rx_itemsWithCellFactory) {(tableView, row, item) in
                let cell = UITableViewCell()
                cell.textLabel?.text = item.distance
    
                return cell
    
            }.addDisposableTo(disposeBag)
    

    If you are using a custom cell then you can use tableView.rx_itemsWithCellIdentifier("ChoiceCell", cellType: ChoiceCell.self). Here is an example:

     currentQuestion
         .asObservable()
         .filter { $0 != nil }
         .map { $0!.choices }
      .bindTo(tableView.rx_itemsWithCellIdentifier("ChoiceCell", cellType: ChoiceCell.self)) { (row, element, cell) in
       cell.choiceModel = element
     }
     .addDisposableTo(disposeBag)
    

    For me I was still getting this same error unless I had a property inside the tableView cell that matched the element that was coming out of the array I was binding the tableView to.

    So if you have an array of [Taxis] like so then inside the tableViewCell I required a variable that stored a Taxis. Then I was able to compile my project.

    So in ChoiceCell I have a var like so:

    var taxi: Taxi? {
        didSet {
            layoutCell()
        }
    

    }

    I hope this helps anyone else having issues binding a tableViewCell to an array.