Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Example of Reactive Cocoa binding for a reusable cell.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:REUSABLE_CELL_ID];
UILabel *label = (UILabel *)[cell viewWithTag:VIEW_TAG];
Model *someModel = [self getModelFromIndexPath:indexPath];
// `takeUntil:` makes the RACObserve() signal complete (and thus breaks the subscription)
// when the cell is recycled.
RAC(label, text) = [RACObserve(someModel, someKey)
takeUntil:cell.rac_prepareForReuseSignal];
return cell;
}
@tmtk75
Copy link

tmtk75 commented May 3, 2014

This is very helpful for me! Thanks!

@liyong03
Copy link

liyong03 commented Jun 28, 2014

That's very good, Thanks.

@alphatroya
Copy link

alphatroya commented Nov 25, 2014

Thanks, very helpful

@anngoman
Copy link

anngoman commented Jul 3, 2015

You saved my life

@bimawa
Copy link

bimawa commented Sep 11, 2015

Yes i need it! Thx!

@dks0280703
Copy link

dks0280703 commented Nov 19, 2015

Just what I was looking for. Thank you!

@aehlke
Copy link

aehlke commented Jan 3, 2016

Yup.

@peiweichen
Copy link

peiweichen commented Jan 15, 2016

Thank a lot!

@icamchu
Copy link

icamchu commented Feb 28, 2016

really useful code snip!
thx~

@adin283
Copy link

adin283 commented Mar 15, 2016

Great!!!

@ivanornes
Copy link

ivanornes commented Jul 18, 2016

How it would be the in swift?

Thanks!

@ivanornes
Copy link

ivanornes commented Jul 18, 2016

I found a solution with the REX extensions
myLabel.rex_text <~
myViewModel.myLabelValue.producer.take(until: self.rex_prepareForReuse)

@CharlesW95
Copy link

CharlesW95 commented Jul 26, 2016

I'm still getting errors using this approach: I'm trying to bind a UITextField's signal to a property in my viewModel.

After tracking when each cell calls "prepareForReuse" and when the tableView delegate calls "cellForRowAtIndexPath", it appears that the "prepareForReuse" method is not called nearly as often as the "cellForRowAtIndexPath" method. Since the binding happens within "cellForRowAtIndexPath", this means that another binding is often attempted on a previously bound property on the viewModel (before the cell gets reused), leading to an assertion failure.

I've tried to manage the binding calls myself by adding a "bound" boolean variable to my viewModel that gets set to true after each binding and only gets set to false when the relevant cell gets reused. I only bind when bound == false. This appears to work 80% of the time, but after some heavy scrolling and pushing the cells off the screen, the assertion error shows up again.

Do you know if there's any way around this?

@tunidev
Copy link

tunidev commented Aug 2, 2016

@CharlesW95 did you find a solution please ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment