如何计算通过cellForRowAtIndexPath中的开关设置的单元格的heightForRowAtIndexPath。

我像这样设置我的单元格:

所以,一些开关定义了单元格,因为数据不在对象列表中,而是一组应该以不同方式显示在tableView中的信息。

-(UITableViewCell *)value1CellForTableView:(UITableView *)tableView { static NSString *CellIdentifierValue1 = @"Value1Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifierValue1]; if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifierValue1]; cell.detailTextLabel.textAlignment = UITextAlignmentLeft; cell.textLabel.textAlignment = UITextAlignmentLeft; } return cell; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = nil; switch (indexPath.section) { case 0: //Coupon switch (indexPath.row) { case 0: //Couponcode cell = [self value1CellForTableView:tableView]; cell.textLabel.text = @"Code"; cell.detailTextLabel.text = presentedCoupon.couponNr; break; case 1: //Coupondescription cell = [self value1CellForTableView:tableView]; cell.detailTextLabel.text = presentedCoupon.couponDescription; cell.detailTextLabel.numberOfLines = 0; cell.textLabel.text =@"Ihr Vorteil"; break; } break; case 1: //Productinfo switch (indexPath.row) { case 0: cell = [self defaultCellForTableView:tableView]; cell.imageView.image = [UIImage imageWithContentsOfFile:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: [presentedCoupon.refProdName stringByAppendingString:@".png"]]]; cell.textLabel.text = presentedCoupon.refProdName; break; } break; case 2: //Shopinfo switch (indexPath.row) { case 0: cell = [self defaultCellForTableView:tableView]; cell.textLabel.text = ((Shop*)presentedCoupon.refShop).name; cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton; break; } break; } if (cell == nil) { cell = [self defaultCellForTableView:tableView]; cell.textLabel.text = @"Stanni"; } [cell layoutIfNeeded]; return cell; } 

我计算这样的高度。

  -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ NSLog(@"height"); UITableViewCell *cell = [self tableView:tableView cellForRowAtIndexPath:indexPath]; CGFloat height = 24 + [cell.detailTextLabel.text sizeWithFont:cell.detailTextLabel.font constrainedToSize: CGSizeMake(cell.detailTextLabel.frame.size.width, 1000.0f) lineBreakMode:cell.detailTextLabel.lineBreakMode].height; return MAX(height, 44.0f); 

问题:

问题是,正如许multithreading中提到的那样,在我的日志中也可见,每个单元格的高度(可见与否)在表视图的初始化时被询问。 所以在更大的100多个列表中,还会创build100多个单元 – 在启动时浪费掉。

如果有这样的单元格设置,还有另外一种可能性来获取这些信息吗? 是否真的需要在heightForRowAtIndexPath中再次构build开关结构,以避免这些调用,并为每个单元格获得正确的高度?

把每个单元格的单一信息放在一个“数据源列表”中会更好吗?

但是如何处理不同的单元格样式,自定义单元格。

两种可能性:

  1. 你有多less个细胞? 如果你有less量的单元格(这里似乎是这种情况),你不需要重用单元格! 一般来说,电池重复使用被滥用。 在创build控制器或者更新数据并将其放入NSArray时,只需创build单元格。
    然后你可以从tableView:cellForRowAtIndexPath:返回它们,或者测量它们的高度。

  2. 创build一个单独的方法,返回单元格文本/字体,并在两个委托方法中使用它,而不是直接从单元格中读取信息。

方法

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

在方法之前调用每个单元格

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

所以在第一种方法中,单元格尚未创build,您不应该尝试访问它们。

当你创build一个tableView时,首先要求数据源的行数。 然后,对于每一行,数据源被要求提供行的高度,以便tableView知道其内容的总高度,最后,数据源被要求显示单元格(实际视图)。

在你的情况下,我会再次build立开关盒结构。 关于“数据源列表”,我从来没有做过,所以也许这是一个更好的解决scheme。

如果你在对象中有一个string数组,然后使用标准表格单元格,那么试试这个iOS 7兼容的魔术:

 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ NSString* text = [self.objects objectAtIndex:indexPath.row]; NSAttributedString * attributedString = [[NSAttributedString alloc] initWithString:text attributes: @{ NSFontAttributeName: [UIFont systemFontOfSize:18]}]; //its not possible to get the cell label width since this method is called before cellForRow so best we can do //is get the table width and subtract the default extra space on either side of the label. CGSize constraintSize = CGSizeMake(tableView.frame.size.width - 30, MAXFLOAT); CGRect rect = [attributedString boundingRectWithSize:constraintSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) context:nil]; //Add back in the extra padding above and below label on table cell. rect.size.height = rect.size.height + 23; //if height is smaller than a normal row set it to the normal cell height, otherwise return the bigger dynamic height. return (rect.size.height < 44 ? 44 : rect.size.height); } 

正如我所看到的 – 你只有两种细胞types。 所以你可能有一个@property为每种types的单元格(请看看下面的例子):

 static NSString * const kCellIdentifier = @"kCellIdentifier"; @interface ... @property (nonatomic, retain) UITableViewCell *cell; @end @implementation @synthesize cell = cell_; ... - (UITableViewCell *)cell { if (!cell_) { cell_ = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:kCellIdentifier]; } return cell_; } - (UITableViewCell *)cellForTableView:(UITableView *)tableView { UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier]; if (!cell) { //put it to autorelease pool to avoid EXC_BAD_ACCESS cell = [[self.cell retain] autorelease]; self.cell = nil; } return cell; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = self.cell; CGFloat height = 24 + [@"text" sizeWithFont:cell.detailTextLabel.font constrainedToSize: (CGSize){cell.detailTextLabel.frame.size.width, CGFLOAT_MAX} lineBreakMode:cell.detailTextLabel.lineBreakMode].height; return MAX(height, 44.0f); } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell = [self cellForTableView:tableView]; cell.detailTextLabel = @"text"; return cell; } 

所以这个单元一开始只会被初始化一次。