在 UITableViewCell 内动画 UILabel 文本更改

Posted

技术标签:

【中文标题】在 UITableViewCell 内动画 UILabel 文本更改【英文标题】:Animate UILabel text change inside UITableViewCell 【发布时间】:2014-06-04 01:00:12 【问题描述】:

当文本属性更改时,我想在自定义UITableViewCell 中为UILabel 设置动画。

我的动画工作正常,除了每次滚动时单元格进入视野时动画都会触发,并且在调用[myTableView reloadData] 时也会触发。

使用简单的东西

if (![myLabel.text isEqualToString:newText]) 
    // change myLabel.text with animation here. 

不起作用。

我明白为什么会这样。 如果我每次都创建一个新单元格,我可以检查myLabel.text 是否有一个字符串,如果有,它是否不同,然后应用更改。但是,有时要显示的单元格太多。

重用单元格时,myLabel.text 几乎总是已经有一个字符串,并且几乎总是与我想要设置的不同。所以上述检查将不起作用。无论如何,它们都会导致动画触发。

我能想到的唯一方法是使用myLabel.text 中的最后一个已知值创建一个数组并进行比较,但这个列表会很大!

我不知道从哪里开始解决这个问题。

我想要的只是myLabeltext 属性更改时在我的子类UITableViewCell 中做一个小翻转/背景颜色动画。我找到的最接近的解决方案将导致 tableviewcell 中的 all 标签运行动画。

我也不能在给它一个字符串之前检查myLabel.text,因为它总是被重复使用。

我开始觉得这是做不到的。

【问题讨论】:

这是UITableViewCell 的子类吗? 是的。我应该在我的问题中提到这一点吗? 是的,应该说清楚。 好的,已修复。谢谢。 在不知道您到底想看到什么的情况下,很难说您应该做什么。例如,如果您将一个新项目插入到您的数组中(在中间某处),您是否希望该标签下方的所有标签都进行动画处理,因为数据正在移动到新单元格(再往下),或者只为您要添加的单元格?我认为解决方案将只涉及更新更改的单元格(使用 reloadRowsAtIndexPaths),而不是使用 reloadData 更新整个表。 【参考方案1】:

如果您继承了UITableViewCell,您可以覆盖默认的prepareForReuse 方法。在此方法中,将标签的 text 属性设置为 nil

- (void)prepareForReuse 
    [super prepareForReuse];
    myLabel.text = nil;

现在:

if (myLabel.text && ![myLabel.text isEqualToString:newText]) 
    // change myLabel.text with animation here. 

现在,只有在将文本从一个文本更改为新文本时,该文本才应该具有动画效果。

prepareForReuse 由 tableview 的 dequeueReusableCell 方法在单元格上调用。

【讨论】:

感谢您抽出宝贵的时间来回答,但是,这并不像我想要的那样工作。当我调用 [tableView reloadData] 时,动画不起作用。这很重要,因为我可以重新加载 UILabel 的唯一方法是通过更新 tableview,并且每次发生这种情况时标签都设置为 nil。 实际上可能有。【参考方案2】:
#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];

【讨论】:

【参考方案3】:

我会像这样在自定义单元格上定义一个方法:

   - (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;
    

然后在 tableView 的 cellForRowAtIndexPath 中调用该方法。棘手的是,当用户滚动或数据更改时(即每次调用 reloadData),cellForRowAtIndexPath 可能会被多次调用。

【讨论】:

这个我试过了。滚动时,单元格会被重复使用,并且几乎总是会初始化 myLabel 并在其重复使用的单元格的 text 属性中保存一些字符串。所以这个 if 语句,总是会返回 yes。 嗯,好的,那么正如 nhgrif 提到的,您只需在自定义单元格类的 prepareForReuse 中将标签文本设置为 nil。 是的,但是每次调用 [tableView reloadData] 或滚动视图时,所有 myLabel.text 属性都设置为 nil。这意味着上面的 if 语句将始终返回 NO。并且不会触发任何动画。【参考方案4】:

我设法通过跟踪 myLabel.text 中保存的先前值来使其工作。

我在名为 previousStrings 的 viewController 上创建了一个 NSMutableDictionary。每个键都是indexPath.row,每个值都是该行的字典。

这是来自cellForRow 方法内部的一些代码。

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]];

那就换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"];

毕竟,在cellForRow 的末尾一定要把字符串字典放回previousStrings

[_previousStrings setObject:strings forKey:[NSString stringWithFormat:@"%d", indexPath.row]];

我希望这对于遇到同样问题的其他人来说是有意义的。 如果不够清楚,请随时编辑并提出问题。

这就是字典的结构。数字是每个单元格的 indexPaths。

【讨论】:

以上是关于在 UITableViewCell 内动画 UILabel 文本更改的主要内容,如果未能解决你的问题,请参考以下文章

如何最好地为 UITableViewCell 或 UIButton 设置动画以重复亮起红色

UItableviewcell中的多行UIlabel使用Autolayout

UniversalImageLoader的用法总结

UITableViewCell 在插入动画完成后立即添加动画

UITableViewCell 背景色动画

当动画 UIImage 被分配两次时,UITableViewCell 中的 UIImageView 没有动画