Определение размера UILabel?

Как изменить следующий фрагмент (в методе tableView: cellForRowAtIndexPath: UITableViewController) из рецепта "09a - PrefsTable" из главы 6 "Поваренной книги разработчиков iPhone":

if (row == 1) { 
    // Create a big word-wrapped UILabel 
    cell = [tableView dequeueReusableCellWithIdentifier:@"libertyCell"]; 
    if (!cell) { 
        cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:@"libertyCell"] autorelease]; 
        [cell addSubview:[[UILabel alloc] initWithFrame:CGRectMake(20.0f, 10.0f, 280.0f, 330.0f)]]; 
    } 
    UILabel *sv = [[cell subviews] lastObject]; 
    sv.text =  @"When in the Course of human events, it becomes necessary for one people to dissolve the political bands which have connected them with another, and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation."; 
    sv.textAlignment = UITextAlignmentCenter; 
    sv.lineBreakMode = UILineBreakModeWordWrap; 
    sv.numberOfLines = 9999; 
    return cell; 
} 

... размер "sv" поднабора UILabel, а "ячейка" UITableViewCell будет иметь размер, достаточно большой, чтобы соответствовать тексту (и работать с более или менее текстом и другими типами выравнивания текста)? Я посмотрел на метод UILabel textRectForBounds: limitedToNumberOfLines:, но в документации указано, что его нельзя вызывать напрямую (и его следует переопределять). Я экспериментировал с методом UIView sizeToFit без успеха.

Обновление: Я задал новый вопрос о своей проблеме с методом NSString -sizeWithFont: forWidth: lineBreakMode:.

Ответ 1

Я должен был сделать это достаточно, чтобы расширить UILabel, чтобы сделать это для меня:

@interface UILabel (BPExtensions)
- (void)sizeToFitFixedWidth:(CGFloat)fixedWidth;
@end

@implementation UILabel (BPExtensions)


- (void)sizeToFitFixedWidth:(CGFloat)fixedWidth
{
    self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, fixedWidth, 0);
    self.lineBreakMode = NSLineBreakByWordWrapping;
    self.numberOfLines = 0;
    [self sizeToFit];
}
@end

то для того, чтобы метка имела переменную многострочную высоту, но фиксированную ширину просто:

[myLabel sizeToFitFixedWidth:kSomeFixedWidth];

Ответ 2

Вы должны использовать метод NSString -sizeWithFont:forWidth:lineBreakMode: для извлечения связанных метрик для вашей метки.

Ответ 3

Кроме того, измените свойство numberOfLines на 0, если вы собираетесь использовать этот код.

Ответ 4

NSString -sizeWithFont:forWidth:lineBreakMode: фактически не выполняет перенос слов. Вместо этого используйте -sizeWithFont:constrainedToSize:lineBreakMode:, чтобы получить точное значение ширины и высоты для строки.

Ответ 5

Попробуйте следующее:

sv.text =  @"When in the Course of human events, it becomes necessary for one people to dissolve the political bands which have connected them with another, and to assume among the powers of the earth, the separate and equal station to which the Laws of Nature and of Nature God entitle them, a decent respect to the opinions of mankind requires that they should declare the causes which impel them to the separation."; 
sv.textAlignment = UITextAlignmentCenter; 
sv.lineBreakMode = UILineBreakModeWordWrap; 
sv.numberOfLines = 0;
[sv sizeToFit]; 

Ответ 6

Кроме того, вам нужно будет реализовать метод UITableViewDelegate:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath

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

Еще одна заметка - размер до Fit должен работать, если у вас есть количество строк, установленных на 0, как упоминалось ранее. Это даст вам обратно размер с увеличенной высотой, чтобы разместить текст, обернутый словом, в ярлыке, а ширина - в соответствии с шириной оригинальной метки.

Это вам не поможет, хотя вам нужно получить размер в heightForRow до того, как будет получена ячейка, поэтому вам лучше рассчитать требуемую высоту (и, скорее всего, кешировать этот расчет, чтобы не замедлять рендеринг таблицы)

Ответ 7

Вот немного кода, который я использую:

CGSize textSize = [myLabel.text sizeWithFont:myLabel.font];

Ответ 8

У меня была аналогичная проблема, у меня был UITableViewCell, который был разработан в StoryBoards как статическая ячейка. Я использовал [super tableView:cellForRowAtIndexPath:], чтобы получить его. Поэтому я хотел изменить размер "detailTextLabel" в UILabel, чтобы он соответствовал тексту, который я ему задал. Стиль был "Right Detail".

Я просто установил текст в своем tableView:cellForRowAtIndexPath:. И чем в tableView:heightForRowAtIndexPath:, я вернул

UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
return cell.detailTextLabel.frame.size.height

У меня была длинная цепочка. И, наконец, широкая ячейка с 4 строками текста в ярлыке.

Ответ 9

У меня была аналогичная проблема. Я решил это.

В методе cellForRowAtIndexPath задайте размер шрифта по своему желанию.

cell.textLabel.lineBreakMode = UILineBreakModeWordWrap;
cell.textLabel.numberOfLines = 0;    
[cell.textLabel setFont:[UIFont systemFontOfSize:14.0]];
[cell.textLabel sizeToFit];

И в методе heightForRowAtIndexPath увеличьте размер шрифта.

    CGFloat height;

    UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath];
    NSString *text = cell.detailTextLabel.text;
    CGSize constraint = CGSizeMake(320, 20000.0f);
    CGSize size = [text sizeWithFont:[UIFont systemFontOfSize:20.0]     constrainedToSize:constraint lineBreakMode:UILineBreakModeWordWrap];
    CGFloat calHeight = MAX(size.height, 44.0f);
    height =  calHeight + (CELL_CONTENT_MARGIN * 2);

    return height;