使用[tableview reloadData]和[tableview reloadRowsAtIndexPaths:]无法正确调整UITableViewCell的高度

时间:2013-01-25 14:51:34

标签: ios cocoa-touch uitableview

这可能是一个很长的问题,以便我能够解释我遇到的所有问题。 所以,我想实现这样的UI功能:

enter image description here

enter image description here

所以我有一个UITableView,它在一个文件中实现,它的单元格在其他文件中实现TableViewCell.m 我需要点击按钮阅读更多以扩展UILabel与文本消息,如第二个屏幕上和单击关闭消息按钮以恢复UILabel并因此调整TableView单元格(这是一个按钮,我只更改它的图像)。因此,为了调整UILabel的大小,我使用[UILabel sizeToFit]并将label.numberOfLines从3更改为0(据我所知,iOS 6功能)。这里是创建单元格的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:  (NSIndexPath *)indexPath {
CPNTalkCell *cell = (CPNTalkCell *)[tableView  dequeueReusableCellWithIdentifier:kCellIdentifier];
NSString *modelId = [[models objectAtIndex:indexPath.row] valueForKey:@"modelId"];
NSDictionary *model = [[models objectAtIndex:indexPath.row] valueForKey:@"model"];
return [self setupCell:cell forModel:model withId:modelId];
}

在setupCell方法中,我进行了额外的调整,在CPNTalkCell中,单元格被描述为vi IB。 这里是按钮ReadMore事件处理程序的代码,我尝试调整单元格和标签的大小:

-(void)ResizeLabel:(id)sender
{
  UIView* sender_button = (UIView*)sender;
  UIButton* _resizingSenderButton = (UIButton*)sender;
  CGRect _button_before = _resizingSenderButton.frame;
  NSIndexPath* indexPath = [listView indexPathForCell:(UITableViewCell*)[[ sender_button superview]superview ]]; //In such an ugly way may be i
  //access NSIndexpath of the current cell from
  // which button was clicked
  CPNTalkCell *cell = (CPNTalkCell*)[listView cellForRowAtIndexPath:indexPath];
  if (cell.messageLabel.numberOfLines==3) {
  [self.listView  beginUpdates];
  cell.messageLabel.numberOfLines=0;
  [cell.messageLabel sizeToFit];
  _button_before.origin.y = cell.messageLabel.frame.origin.y+ cell.messageLabel.frame.size.height+7;
  _resizingSenderButton.frame=_button_before;
 [_resizingSenderButton setBackgroundImage:[UIImage imageNamed:@"readmore2.png" ] forState:UIControlStateNormal];
 [cell sizeToFit];
 //  [self.listView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
 [self.listView reloadData];
 [self.listView endUpdates];
 }
  else
 {
  cell.messageLabel.numberOfLines = 3;
  [self.listView  beginUpdates];
  [cell.messageLabel sizeToFit];
   CGRect _button_after = _resizingSenderButton.frame;
  _button_after.origin.y = cell.messageLabel.frame.origin.y+ cell.messageLabel.frame.size.height+7;
  _resizingSenderButton.frame=_button_after;
  [_resizingSenderButton setBackgroundImage:[UIImage imageNamed:@"readmore1.png" ] forState:UIControlStateNormal];
  [cell sizeToFit];
  [self.listView reloadData];
  //[self.listView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationTop];
  [self.listView endUpdates];
  }
   }

所以这个代码工作并且在单击单元格后调整大小以适应文本和它的长度但工作奇怪 - 有时按钮消失或在滚动列表按钮后出现在文本上也可能消失甚至文本。我在更改单元格时使用reloadData - 我知道这不是最佳的,但正如你所看到的那样,我已经评论了重新加载一个单元格的代码,因为它在第一次点击时更加奇怪或不起作用。 我也重载了heightForRowatIndexPath:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *modelId = [[models objectAtIndex:indexPath.row] valueForKey:@"modelId"];
NSDictionary *model = [[models objectAtIndex:indexPath.row] valueForKey:@"model"];
CPNTalkCell *cell = [_cells objectForKey:modelId];

if (cell == nil) {
    cell = [self setupCell:nil forModel:model withId:modelId];
}

return cell.rowHeight;
}

但在其中我通过调用TalkCell文件中描述的rowHeight点击按钮之前描述了初始单元格参数!

我知道这是一个很长的问题,我有时会解释清楚,但我认为iOS专家将能够理解我的问题并提出解决这个问题的方法。我真的需要帮助,因为我试着解决这个问题不是一天。

非常感谢提前!

1 个答案:

答案 0 :(得分:0)

您需要重载heightForRowAtIndexPath以根据展开的单元格返回适当的值

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *mode

    lId = [[models objectAtIndex:indexPath.row] valueForKey:@"modelId"];
    NSDictionary *model = [[models objectAtIndex:indexPath.row] valueForKey:@"model"];
    CPNTalkCell *cell = [_cells objectForKey:modelId];

    if (cell == nil) {
        cell = [self setupCell:nil forModel:model withId:modelId];
    }

    if ( indexPath == expandedIndexPath )//save the expanded cell's index path somewhere
    {
        return expandedCellHeight;
    }

    return cell.rowHeight;
}