Фрейм UIView не обновляет размер по времени для создания анимации прокрутки текста в UILabel - PullRequest
0 голосов
/ 07 ноября 2011

Я делаю обычное «добавление ваших собственных меток / изображений в cell.contentview» из контроллера cellForRowAtIndexPath.И я пытаюсь, чтобы одна из меток содержала анимированный текст прокрутки: то есть, если текст в метке выходит за пределы ширины viewCell, метка в ячейке должна прокручивать текст (анимированный - не ручной).Кроме того, весь этот просмотр таблицы и прокрутка текста должны работать как для iPhone, так и для iPad (поэтому все должно быть соответствующим образом автоматически изменено).

Сокращение до погони, вопрос:

Как мне получитьподпредставление cell.contentView для своевременного обновления размера кадра для проверки, переполняется ли текст внутри этого подпредставления или нет.

Или, возможно, это даже правильный путь?

Вот изображение того, что я имею в виду (secondLabel и т. Д. Объяснены ниже):

Теперь вы можете продолжить чтение для деталей:

Способ, которым я пыталсяВ этом случае cellForRowAtIndexPath добавляет пользовательский экземпляр UISCrollLabelView в contentView ячейки.Где этот пользовательский класс действительно UIView, который внутренне управляет UILabel.

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 обновляется до правильного размера.

Вот cellForRowAtIndexPath (secondLabel здесь - scrollView):

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
  UIImageSmartView *cachedImage;
  UILabel *mainLabel;
  UIScrollLabelView *secondLabel;

  static NSString *CellIdentifier = @"Cell";

  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  if (cell == nil) 
  {
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
                                   reuseIdentifier:CellIdentifier] autorelease];

    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    cell.selectionStyle = UITableViewCellSelectionStyleGray;

    mainLabel = [[[UILabel alloc] initWithFrame:CGRectMake(70, 0, 0, 20)] autorelease];
    mainLabel.font = [UIFont boldSystemFontOfSize:18];
    mainLabel.textAlignment = UITextAlignmentLeft;
    mainLabel.textColor = [UIColor blackColor];
    mainLabel.backgroundColor = [UIColor clearColor];
    mainLabel.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin);
    mainLabel.tag = MAINLABEL_TAG;

    secondLabel = [[[UIScrollLabelView alloc] initWithFrame:CGRectMake(70, 40, 0, 20)] autorelease];
    secondLabel.autoresizingMask = (UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleRightMargin);
    //secondLabel.backgroundColor = [UIColor clearColor];
    secondLabel.tag = SECONDLABEL_TAG;

    cachedImage = [[UIImageSmartView alloc] initWithFrame:CGRectMake(5, 5, 57, 80)];
    cachedImage.tag = PHOTO_TAG;

    [cell.contentView addSubview:cachedImage];
    [cell.contentView addSubview:mainLabel];
    [cell.contentView addSubview:secondLabel];

  }
  else
  {
    cachedImage = (UIImageSmartView*)[cell.contentView viewWithTag:PHOTO_TAG];
    mainLabel = (UILabel*)[cell.contentView viewWithTag:MAINLABEL_TAG];
    secondLabel = (UIScrollLabelView*)[cell.contentView viewWithTag:SECONDLABEL_TAG]; 
  }

  // Configure the cell...

  NSString *ImageName = [[dbData objectAtIndex:indexPath.row] objectAtIndex:2];
  NSString *imageURL = [NSString stringWithFormat:@"http://someserver", referencingTable];
  [cachedImage loadAndCacheImageFromFile:ImageName fromURL:imageURL inSize:CGSizeMake(57, 80) withBorderWidth:4];

  mainLabel.text = [[dbData objectAtIndex:indexPath.row] objectAtIndex:0];

  // -> At this point I load the text into the "scrolling label" 
  //    (actually a UIView with a label)
  [secondLabel setScrollingText:[[dbData objectAtIndex:indexPath.row] objectAtIndex:1]];

  return cell;
}

И моя реализация UIScrollLabelView выглядитвот так вот:

@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

1 Ответ

0 голосов
/ 30 января 2012

Вы устанавливаете размер метки, когда размер ячейки еще не определен. И тогда вы никогда не будете проверять реальный размер снова. Вам нужно переопределить setFrame и setBounds, чтобы отследить изменения размера кадра.

...