【问题标题】:Animate custom views of UITableView Section Headers动画 UITableView 部分标题的自定义视图
【发布时间】:2013-05-15 15:04:51
【问题描述】:

在我的应用程序中,我在 Scene 中有一个 UITableView,它动态改变宽度。当宽度发生变化时,我会为场景的扩展设置动画 - 包括 UITableView

UITableView 包含带有自定义视图的节标题,其中包含锚定在视图右侧的 UILabel

当我的场景宽度发生变化时,我会像这样为调整表格大小设置动画:

[UIView animateWithDuration:0.22
                      delay:0.02
                    options:UIViewAnimationOptionCurveLinear
                 animations:^
 {
     //Change width to 320 from 220
     [menuTable setFrame:CGRectMake(menuTable.frame.origin.x, menuTable.frame.origin.y, 320, menuTable.frame.size.height)];
 }
                 completion:^(BOOL finished)
 {

 }];

这可以平滑地为表格的大小调整设置动画,但节标题内的标签会弹出到最终目的地 - 它没有动画。

我试过打电话给reloadData - 效果一样,没有动画。我试过打电话给beginUpdatesendUpdates,但是没有效果。

我还应该尝试什么?

【问题讨论】:

  • 你在使用自动布局吗?
  • UILabel 不会为文本更改设置动画。如果您为标签设置背景颜色,您应该会看到标签框架正确动画,而文本等待然后跳转到位。您需要一个 UILabel 的子类来完全控制文本动画的到位方式。
  • @rdelmar - 我正在使用自动布局。
  • @RyanPoolos - 如果我按照你所说的那样在标签上设置背景颜色,我可以看到它肯定会弹出到位 - 标签本身没有以任何方式设置动画。

标签: iphone ios objective-c uitableview


【解决方案1】:

在我对标签扩展的实验中,我发现 Ryan Poolos 在他的评论中所说的是真的——即使标签用动画扩展,文本也会跳转到它的新位置(我已经对文本做了这个设置为中心对齐)。

所以,我发现唯一可行的方法是使用计时器,如下所示:

-(IBAction)expandLabel:(id)sender {

    [NSTimer scheduledTimerWithTimeInterval:.01 target:self selector:@selector(expand:) userInfo:nil repeats:YES];
}

-(void)expand:(NSTimer *) aTimer {
    self.widthCon.constant += 1;
    if (self.widthCon.constant >= 200) [aTimer invalidate];
}

widthCon 是我放在标签上的宽度约束的 IBOutlet。如果你使用自动布局,你应该通过改变约束来做任何动画,而不是改变框架。我没有尝试在节标题中使用标签,但我认为如果您使用此方法为表格的宽度设置动画,并且标签的约束以遵循表格扩展的方式设置,它将起作用。

编辑后:

经过更多的实验,看来 timer 方法也是使其用于移动标签(而不是扩展标签)的唯一方法。在这种情况下,宽度约束将是 table view 本身。

第二次编辑后:

更多实验。我发现问题在于调用 layoutSubviews(您不应该直接调用)而不是 layoutIfNeeded。因此,您可以在没有计时器的情况下使标签位置动画化。这是我用来制作标题的代码,并在单击按钮时进行扩展:

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
    UITableViewHeaderFooterView *view = [[UITableViewHeaderFooterView alloc] init];
    view.tintColor = [UIColor yellowColor];
    UILabel *label = [[UILabel alloc] init];
    [label setTranslatesAutoresizingMaskIntoConstraints:NO];
    label.backgroundColor = [UIColor redColor];
    label.text = @"Test";
    [view.contentView addSubview:label];
    [view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[label]-|" options:0 metrics:nil views:@{@"label":label}]];
    [view addConstraint:[NSLayoutConstraint constraintWithItem:label attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:view attribute:NSLayoutAttributeCenterY multiplier:1 constant:0]];
    return view;
}

-(IBAction)expandTable:(id)sender {
    self.widthCon.constant = 300;
    [UIView animateWithDuration:1 animations:^{
        [self.view layoutIfNeeded];
    }];
}

【讨论】:

  • 我实际上并没有改变标签的宽度,只是它的位置。所以也许 Ryan Poolos 所说的对于宽度变化是正确的,但对于位置变化,至少在这种情况下,这不是问题。使用计时器手动移动标签的框架可能会起作用,但这很麻烦。我希望这是最后的手段 - 在我看来,应该有一种方法可以向部分标题视图表明它应该动画?
  • @BreadicalMD,好的,对不起,我误解了你的问题。但是我对使用约束进行动画处理的建议仍然有效——如果使用约束对表格的宽度进行动画处理,则标签位置应该正确地跟随。我将更新我的答案以反映这一点。
  • 这也不起作用 :( 不幸的是,试图阻止表格本身的动画 - 它的宽度现在立即改变而不是动画。self.tableWidth.constant = 320; [UIView animateWithDuration:0.22 delay:0.02 options:UIViewAnimationOptionCurveLinear animations:^ { [menuTable layoutSubviews]; [self.view layoutSubviews]; } completion:^(BOOL finished) { }];
  • @BreadicalMD,是的,我也只是对此进行了测试,但标签的动画效果不正确——我仍在寻找解决方案。但对我来说,表格视图和它的标题视图确实可以正确动画,所以我不确定你的为什么没有。
  • 我看不到任何方法可以让部分标题视图及其子视图生成动画。我已经使用了你的动画解决方案——效果很好。现在我只需要用其他动画正确地计时。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-26
  • 2013-03-14
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-18
相关资源
最近更新 更多