如何使UITableView行高响应用户的首选文本大小(动态类型)?

我希望UITableView的行高能够响应用户首选文本大小的变化。 例如,当首选文本大小增加时,我想将行高增加一个比例。 这是我到目前为止所拥有的:

 - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; [self.tableView reloadData]; // observe when user changes preferred text size [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(preferredContentSizeChanged:) name:UIContentSizeCategoryDidChangeNotification object:nil]; } - (void)preferredContentSizeChanged:(NSNotification *)notification { [self.tableView reloadData]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellID = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath]; // leverage Text Kit's Dynamic Type cell.textLabel.font = [UIFont preferredFontForTextStyle:UIFontTextStyleHeadline]; cell.textLabel.text = @"All work and no play..."; return cell; } 

那么,计算反映用户首选文本大小的行高的最佳方法是什么?

我最近完成了这项工作并发现它非常简单。 而不是使用sizeWithFont:您应该在iOS 7中使用新的boundingRectWithSize:options:attributes:context方法。

像往常一样设置表格视图单元格并在文本标签上指定preferredFontForTextStyle:

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TableViewCellIdentifier forIndexPath:indexPath]; //set your table view cell content here [[cell textLabel] setText:@"Lorem ipsum dolour sit amet."]; [[cell textLabel] setNumberOfLines:0]; [[cell textLabel] setLineBreakMode:NSLineBreakByWordWrapping]; [[cell textLabel] setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleBody]]; return cell; } 

然后要正确确定文本标签的大小,请评估boundingRectWithSize:options:attributes:context以计算所需的高度。

 - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { //add your table view cell content here NSString *string = @"Lorem ipsum dolor sit amet."; NSDictionary *attributes = @{NSFontAttributeName: [UIFont preferredFontForTextStyle:UIFontTextStyleBody]}; CGRect frame = [string boundingRectWithSize:CGSizeMake(CGRectGetWidth(tableView.bounds), CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) attributes:attributes context:nil]; return ceilf(CGRectGetHeight(frame); } 

您可能还希望将表视图单元格子类UIContentSizeCategoryDidChangeNotification侦听UIContentSizeCategoryDidChangeNotification通知,此时您可以在用户更改其Settings.app中的首选项时更新UI

 - (void)contentSizeCategoryDidChangeNotificationHandler:(NSNotification *)notification { [[self textLabel] setFont:[UIFont preferredFontForTextStyle:UIFontTextStyleBody]]; } 

如果您需要在文本标签周围添加额外的填充,您可以定义一个常量值,例如

 static CGFloat const TableViewCellPadding = 10.0; 

有了这个,你可以为从tableView:heightForRowAtIndexPath:返回的值添加一个常量值tableView:heightForRowAtIndexPath:

 return (ceilf(CGRectGetHeight(frame) + TableViewCellPadding); 

或者您可以插入从boundingRectWithSize:options:attributes:context返回的帧boundingRectWithSize:options:attributes:context as this:

 CGRect frame = [string boundingRectWithSize:CGSizeMake(CGRectGetWidth(tableView.bounds), CGFLOAT_MAX) options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) attributes:attributes context:nil]; frame = CGRectInset(frame, 0.0, TableViewCellPadding); 

使用此方法:

  - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *fieldLabel = labelCell.textLabel.text; CGSize textSize = [fieldLabel sizeWithFont:[UIFont fontWithName:@"Georgia" size:17.0f] constrainedToSize:CGSizeMake([UIScreen mainScreen].bounds.size.width-20, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping]; float newHeight = textSize.height+22.0f; return newHeight; } 

将以下代码添加到cellForRowAtIndexPath

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *cellID = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID forIndexPath:indexPath]; UILabel *lblfield=[[UILabel alloc] init]; NSString *fieldLabel=[NSString stringWithFormat:@"%@",labelCell.textLabel.text]; CGSize textSize = [fieldLabel sizeWithFont:[UIFont fontWithName:@"Georgia" size:17.0f] constrainedToSize:CGSizeMake([UIScreen mainScreen].bounds.size.width-20, MAXFLOAT) lineBreakMode:NSLineBreakByWordWrapping]; float newHeight = textSize.height+22.0f; lblfield.frame=CGRectMake(10, 0, [UIScreen mainScreen].bounds.size.width, newHeight); lblfield.backgroundColor=[UIColor clearColor]; lblfield.text=strusername; [cell addSubview:lblfield]; return cell; }