简体   繁体   中英

Resizing height of UITableViewCell doesn't work correctly neither with [tableview reloadData] nor with [tableview reloadRowsAtIndexPaths:]

This may be a long question in order I'll be able to explain all the problem I've encountered. So, I want to implement such UI functionality:

在此处输入图片说明

在此处输入图片说明

So I have a UITableView which is implemented in one file and it's cells which is implemented in other file TableViewCell.m And I need after clicking on button read more to expand UILabel with text mesage as on the second screen and after clicking on close message button to restore UILabel and consequently resize TableView cell (this is one button i only change images of it). So in order to resize UILabel I use [UILabel sizeToFit] and change label.numberOfLines from 3 to 0 (iOS 6 feature as far as I know).And here code of creating cells:

- (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];
}

In setupCell method I do additional adjustments and in CPNTalkCell the cell is described vi IB. And here the code of button ReadMore event handler where I try to resize cell and label:

-(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];
  }
   }

So this code work and after clicking cells resize to fit the text and it's length but works strange - sometimes buttons disappear or appear on the text after scrolling the list buttons also may disappear or even text.I use reloadData when I change cell - i know it's not optimal, but as you see I've commented code of reloading of one cell because it works even more strange or not from the first clicking. I also overload 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;
}

But in it i describe initial cell parameters before clicking on a button via calling of rowHeight described in TalkCell file!

I know it's a long question and I sometimes explain not all clear but I think iOS experts will be able to understand my problem and propose solution of this problem. I really need a help because I try to solve this problem not for a one day.

Great thanks in advance!

You need to overload heightForRowAtIndexPath to return the appropriate value based on the expanded cell

- (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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM