Skip to content

Instantly share code, notes, and snippets.

@bunnyhero
Last active February 19, 2022 02:04
Show Gist options
  • Save bunnyhero/9988574 to your computer and use it in GitHub Desktop.
Save bunnyhero/9988574 to your computer and use it in GitHub Desktop.
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;
}
@liyong03
Copy link

That's very good, Thanks.

@alphatroya
Copy link

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

Just what I was looking for. Thank you!

@aehlke
Copy link

aehlke commented Jan 3, 2016

Yup.

@peiweichen
Copy link

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

How it would be the in swift?

Thanks!

@ivanornes
Copy link

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

@CharlesW95
Copy link

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