iOS — проблемы с динамическим изменением размера tableviewcell

Я знаю, что здесь уже есть много потенциальных ответов на этот вопрос, но 99,995% всех ответов, которые я видел, используют sizeWithFont, который теперь устарел.

У меня есть одна табличная ячейка, с которой я имею дело, поэтому она должна быть простой, но у меня ничего не получается. вот код, который был составлен, прочитав некоторые ответы в Интернете. Это для метки ячейки.

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  NSString *myString = [self.locations[indexPath.row] locationDescription];
  return [self heightForText:myString] + 44.0;
}

-(CGFloat)heightForText:(NSString *)text{

  NSInteger MAX_HEIGHT = 10000;
  UILabel *cellLabelView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, MAX_HEIGHT)];
  cellLabelView.text = text;
  cellLabelView.font = [UIFont fontWithName:@"Helvetica Neue Light" size:18];
  [cellLabelView sizeToFit];
  return cellLabelView.frame.size.height;
}

Высота, определенная в раскадровке, установлена ​​​​на 44, а строки установлены на 0 для самой метки, чтобы метка могла решить, насколько большой она должна быть.

Проблема № 1: Если текст, установленный для метки, не переносится по словам, я все равно (очевидно) получаю дополнительное дополнение, которое мне не нужно. Я не уверен, как рассчитать, был ли на самом деле перенос слов или нет. Если не было переноса слов (т.е. текст не был длиннее метки, то я просто хочу вернуть 44).

Проблема № 2: По какой-то причине, если мой текст слишком длинный, например, 5 строк, часть текста в конце строки по какой-то причине обрезается, несмотря на то, что MAXHEIGHT составляет 10 000, это почти так, как будто это решает прекратить перенос слов. Если я увеличу отступ в этот момент, скажем, до 88, тогда я все увижу. (Странный).

Ищу элегантные решения, отзывы, помощь, что угодно. Спасибо!


person cspam    schedule 10.02.2014    source источник


Ответы (1)


sizeWithFont: в NSString действительно устарела в iOS 7, но заменена на sizeWithAttributes:. Для многострочного текста полезно использовать boundingRectWithSize:options:attributes:context:. Видеть

iOS 7 sizeWithAttributes: замена sizeWithFont:constrainedToSize

для соответствующей альтернативы вашему методу UILabel.

Проблема № 1: я не уверен, что именно вы хотите получить здесь. Если вы хотите иметь постоянный отступ выше и ниже вашего UILabel, но с минимальной высотой ячейки 44 пункта, вы можете сделать что-то вроде:

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  NSString *myString = [self.locations[indexPath.row] locationDescription];
  CGFloat myPadding = 20.0; // for example
  return MAX([self heightForText:myString] + myPadding, 44.0);
}

Однако, если вы хотите каким-то образом основывать высоту ячейки на количестве строк текста, тогда будет работать деление вычисленной высоты на свойство lineHeight UIFont и округление:

NSUInteger numberOfLines = roundf(calculatedTextHeight / font.lineHeight);

Проблема № 2: этикетка, которую вы создаете для расчета высоты, не имеет numberOfLines, установленного на 0, поэтому не будет рассчитана для многострочной этикетки.

Я думаю, что метод NSString — лучший путь для снижения, но в стороне, если вы хотите использовать подход UILabel, я бы рекомендовал создать метку только один раз, чтобы повысить производительность прокрутки UITableView, например.

-(CGFloat)heightForText:(NSString *)text{
  NSInteger MAX_HEIGHT = 10000;
  static UILabel *cellLabelView = nil;
  if (!cellLabelView)
  {
     cellLabelView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 320, MAX_HEIGHT)];
     cellLabelView.text = text;
     cellLabelView.font = [UIFont fontWithName:@"Helvetica Neue Light" size:18]; 
     cellLabelView.numberOfLines = 0;     
  } 
  return [cellLabelView sizeThatFits:CGSizeMake(320, MAX_HEIGHT)].height;
}
person stefandouganhyde    schedule 10.02.2014