I want to animate a UILabel
inside a custom UITableViewCell
when the text property changes.
I have the animation working fine, except the animation is firing every time the cell comes into view while scrolling and also when calling [myTableView reloadData]
.
Using something as simple as
if (![myLabel.text isEqualToString:newText]) {
// change myLabel.text with animation here.
}
Does not work.
I understand why this is happening. If I create a new cell each time, I could check if myLabel.text
has a string, if so, is it different, and then apply the changes. However there are sometimes way too many cells to display.
When reusing cells, myLabel.text
will almost always already have a string, and will almost always be different to what I want to set it to. So the above checks won't work. They will cause the animations to fire anyway.
The only way I can think of getting this to work is to create an array with the last known values in myLabel.text
and do a comparison, but this list would be huge!
I have no idea where to begin solving this issue.
All I want is for myLabel
to do a little flip/backgroundColor animation inside my subclassed UITableViewCell
when the text
property changes. The closest solutions I have found will cause all labels in the tableviewcell to run the animation.
I also can't check myLabel.text
before giving it a string because it's always getting reused.
I'm starting to get the impression that this just can't be done.
If you've subclassed UITableViewCell
, you can override the default prepareForReuse
method. In this method, set your label's text property to nil
.
- (void)prepareForReuse {
[super prepareForReuse];
myLabel.text = nil;
}
Now:
if (myLabel.text && ![myLabel.text isEqualToString:newText]) {
// change myLabel.text with animation here.
}
Now the text should only animate if it's been changed from one text to a new text.
prepareForReuse
is called on the cell by the tableview's dequeueReusableCell
method.
#pragma mark - Timer Function
-(void)callAfteroneSecond_deals
{
NSArray *indexes = [self.tbl_deals indexPathsForVisibleRows];
MYTableViewCell *cell = (MYTableViewCell *)[_tbl_deals cellForRowAtIndexPath:index];
cell.lbl_expiredtime.text=@"Hello";
[cell.contentView bringSubviewToFront:cell.lbl_expiredtime];
}
I would define a method on the custom cell like so:
- (void) updateMyLabel: (NSString *)newText {
// If the new value is different than what is already set,
// and the label isn't nil, then trigger the animation
if (self.myLabel.text && self.myLabel.text != newText) {
[UIView animateWithDuration...];
}
self.myLabel.text = newText;
}
Then call that method in your tableView's cellForRowAtIndexPath. The tricky thing is that cellForRowAtIndexPath can get called multiple times as the user scrolls around, or as data changes (ie every time you call reloadData).
I managed to get it to work by keeping track of the previous values held in myLabel.text
.
I created an NSMutableDictionary
on my viewController named previousStrings
. With each key being an indexPath.row
, and each value being a dictionary for that row.
Here's some code from inside cellForRow
method.
NSMutableDictionary *strings;
// check to see if previousStrings already has a dictionary at key of indexPath.row
// if not, then create one.
if (![_previousStrings objectForKey:[NSString stringWithFormat:@"%d", indexPath.row]]) {
strings = [[NSMutableDictionary alloc] init];
}
else {
strings = [_previousStrings objectForKey:[NSString stringWithFormat:@"%d", indexPath.row]];
}
Then change myLabel.text
NSString *cellText = newTextString;
// If the new string is equal to the old string, just set the label without animation
// otherwise run animation and update the value inside the strings dictionary.
if ([strings[@"myLabel"] isEqualToString:newTextString]) {
cell.myLabel.text = newTextString;
}
else {
[cell.myLabel runTextChangeAnimationWithString:newTextString];
[strings setObject:newTextString forKey:@"myLabel"];
}
After all that, at the end of cellForRow
be sure to put the strings dict back into previousStrings
[_previousStrings setObject:strings forKey:[NSString stringWithFormat:@"%d", indexPath.row]];
I hope this makes sense for anyone else stumbling across the same issue. Feel free to edit and ask questions if it's not clear enough.
This is how the dictionaries are structured. Numbers being the indexPaths of each cell.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.