Ios UIView帧未及时更新大小以在UILabel中创建滚动文本动画

Ios UIView帧未及时更新大小以在UILabel中创建滚动文本动画,ios,uitableview,core-animation,uilabel,nstimer,Ios,Uitableview,Core Animation,Uilabel,Nstimer,我在控制器的cellForRowAtIndexPath中执行通常的“向cell.contentview添加您自己的标签/图像”。我试图让其中一个标签具有动画滚动文本:也就是说,如果标签中的文本溢出了viewCell宽度,则单元格中的标签应滚动文本(动画-非手动)。此外,整个tableview+滚动文本应该适用于iPhone和iPad(因此所有内容都需要相应地自动调整大小) 直截了当地说,问题是: 如何获取cell.contentView的子视图以及时更新其帧大小,以便测试此子视图中的文本是否溢出

我在控制器的cellForRowAtIndexPath中执行通常的“向cell.contentview添加您自己的标签/图像”。我试图让其中一个标签具有动画滚动文本:也就是说,如果标签中的文本溢出了viewCell宽度,则单元格中的标签应滚动文本(动画-非手动)。此外,整个tableview+滚动文本应该适用于iPhone和iPad(因此所有内容都需要相应地自动调整大小)

直截了当地说,问题是:

如何获取cell.contentView的子视图以及时更新其帧大小,以便测试此子视图中的文本是否溢出

或者,这是正确的方式吗

下面是我的意思(secondLabel等解释如下):

现在,您可以继续阅读以下详细信息:

我尝试的方法是让cellForRowAtIndexPath将自定义UISCrollLabelView实例添加到单元格的contentView中。其中,该自定义类实际上是一个在内部管理UILabel的UIView

UISCrollLabelView应该自动调整大小,使其不会溢出表格单元格(应该适用于iPhone和iPad)。然后,根据cellForRowAtIndexPath传递给它的文本长度,它应该自动调整其内部标签的大小以适应所有文本,如果标签最终溢出视图(self),则设置UILabel滚动的动画

我对此有几个问题,但主要问题是:UIScrollableView会根据内部标签的frame.size.width与self.frame.size.width的比较来触发(或不触发)动画。但是很明显,self的帧宽度需要一些时间才能从0更新到插入cell.contenView后的大小。这意味着,当我的自定义UIScrollLabelView测试
(label.frame.size.width>self.frame.size.width)
时,这总是正确的,不会溢出的文本仍会滚动。大约一秒钟后,self.frame会更新到正确的大小

这是CellForRowatineXpath(
secondLabel
是此处的滚动视图):

到目前为止,我的
uiscrollabelview
实现如下所示:

@implementation UIScrollLabelView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) 
    {
        // Initialization code
      isScrolling = NO;

      self.clipsToBounds = YES;
      UILabel *label = [[[UILabel alloc] init] autorelease];
      label.font = [UIFont systemFontOfSize:14.0];
      label.textAlignment = UITextAlignmentLeft;
      label.textColor = [UIColor darkGrayColor];
      label.backgroundColor = [UIColor greenColor];
      self.backgroundColor = [UIColor redColor];
      //label.backgroundColor = [UIColor clearColor];

      [self addSubview: label];

    }
    return self;
}

- (void)setScrollingText:(NSString*)text
{
  [self setNeedsLayout];
  UILabel *label = [[self subviews ] objectAtIndex:0];
  label.text = text;
  [label sizeToFit];

  if(label.frame.size.width > self.frame.size.width)
    [self scrollText];

}

- (void)scrollText
{
  if(isScrolling)
        return;

  isScrolling = YES;

  UILabel *label = [[self subviews ] objectAtIndex:0];

    [UIView beginAnimations:@"scroll" context:nil];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationCurve:UIViewAnimationCurveLinear];
    [UIView setAnimationDidStopSelector:@selector(scrollDidComplete)];
    [UIView setAnimationDuration: label.frame.size.width/(float)100];

    CGRect frame = label.frame;
    if(frame.origin.x == 0)
      frame.origin.x = frame.origin.x - (frame.size.width - self.frame.size.width); 
    else
      frame.origin.x = 0;

    label.frame = frame;    
    [UIView commitAnimations];

}

- (void)scrollDidComplete
{
  isScrolling = NO;
  [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(scrollText) userInfo:nil repeats:NO];
} 


@end

当单元格的大小尚未定义时,您正在设置标签大小。然后你再也不会检查实际尺寸了。 您需要覆盖setFrame和setBounds以捕捉帧大小的更改

@implementation UIScrollLabelView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) 
    {
        // Initialization code
      isScrolling = NO;

      self.clipsToBounds = YES;
      UILabel *label = [[[UILabel alloc] init] autorelease];
      label.font = [UIFont systemFontOfSize:14.0];
      label.textAlignment = UITextAlignmentLeft;
      label.textColor = [UIColor darkGrayColor];
      label.backgroundColor = [UIColor greenColor];
      self.backgroundColor = [UIColor redColor];
      //label.backgroundColor = [UIColor clearColor];

      [self addSubview: label];

    }
    return self;
}

- (void)setScrollingText:(NSString*)text
{
  [self setNeedsLayout];
  UILabel *label = [[self subviews ] objectAtIndex:0];
  label.text = text;
  [label sizeToFit];

  if(label.frame.size.width > self.frame.size.width)
    [self scrollText];

}

- (void)scrollText
{
  if(isScrolling)
        return;

  isScrolling = YES;

  UILabel *label = [[self subviews ] objectAtIndex:0];

    [UIView beginAnimations:@"scroll" context:nil];
    [UIView setAnimationBeginsFromCurrentState:YES];
    [UIView setAnimationDelegate:self];
    [UIView setAnimationCurve:UIViewAnimationCurveLinear];
    [UIView setAnimationDidStopSelector:@selector(scrollDidComplete)];
    [UIView setAnimationDuration: label.frame.size.width/(float)100];

    CGRect frame = label.frame;
    if(frame.origin.x == 0)
      frame.origin.x = frame.origin.x - (frame.size.width - self.frame.size.width); 
    else
      frame.origin.x = 0;

    label.frame = frame;    
    [UIView commitAnimations];

}

- (void)scrollDidComplete
{
  isScrolling = NO;
  [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(scrollText) userInfo:nil repeats:NO];
} 


@end