Reputation: 1360
I have a label in a TableViewCell in which there are more than one lines of text. Initially on the label it shows only one line. I have a button on that cell. I want to expand the cell by clicking on the button upto the hight of the label's text.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"tabCell";
_cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
// Configure the cell...
NSManagedObject *device = [self.persons objectAtIndex:indexPath.row];
UILabel *nameLabel = (UILabel*)[_cell.contentView viewWithTag:2];
nameLabel.text = [NSString stringWithFormat:@"%@", [device valueForKey:@"name"]];
UILabel *dateLabel = (UILabel *)[_cell.contentView viewWithTag:3];
dateLabel.text = [NSString stringWithFormat:@"%@",[device valueForKey:@"date"]];
UILabel *descLabel = (UILabel *)[_cell.contentView viewWithTag:4];
//descTextView.text = [NSString stringWithFormat:@"%@",[device valueForKey:@"desc"]];
UIImageView *personImage = (UIImageView *)[_cell.contentView viewWithTag:1];
UIImage *personImg = [UIImage imageWithData:[device valueForKey:@"image"]];
personImage.image = personImg;
UIButton *viewMoreButton = (UIButton *)[_cell.contentView viewWithTag:5];
[viewMoreButton addTarget:self
action:@selector(myAction)
forControlEvents:UIControlEventTouchUpInside];
NSAttributedString *attrString = [[NSAttributedString alloc] initWithString:[device valueForKey:@"desc"]
attributes:@{ NSFontAttributeName:[UIFont fontWithName:@"HelveticaNeue" size:17]}];
reqFrame=[attrString boundingRectWithSize:CGSizeMake(descLabel.frame.size.height, CGFLOAT_MAX)options:NSStringDrawingUsesLineFragmentOrigin
context:nil];
descLabel.attributedText = attrString;
return _cell;
}
- (void)myAction{
//what to write here?
}
Upvotes: 1
Views: 1432
Reputation: 1202
you need to maintain two variables, just give tag to your button, and detect in action by its tag to reload that particular cell and another BOOL variable to detect if button touched. You should calculate height in heightForRowAtIndexPath method. I am posting code, it may help you
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if(isReadMoreButtonTouched && [indexPath row]== indexOfReadMoreButton) {
NSString *yourText = [arr1 objectAtIndex:indexPath.row]; // your text
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:@"Avenir Next" size:14], NSFontAttributeName,
[UIColor grayColor], NSForegroundColorAttributeName,
nil]; // set custom attributes
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:yourText attributes:attributes];
CGRect paragraphRect = [attributedText boundingRectWithSize:CGSizeMake(625, CGFLOAT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
context:nil]; //here 625 is width of label
NSLog(@"height = %f", paragraphRect.size.height);
return paragraphRect.size.height;
}
else{
return 200; //default height taken in storyboard
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
cell.lblKB.text = [arr objectAtIndex:indexPath.row];
cell.lblDetail.text = [arr1 objectAtIndex:indexPath.row];
NSString *yourText = [arr1 objectAtIndex:indexPath.row];
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:
[UIFont fontWithName:@"Avenir Next" size:14], NSFontAttributeName,
GrayColor, NSForegroundColorAttributeName,
nil]; //your custom attributes
NSAttributedString *attributedText = [[NSAttributedString alloc] initWithString:yourText attributes:attributes];
CGRect paragraphRect = [attributedText boundingRectWithSize:CGSizeMake(625, CGFLOAT_MAX)
options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading)
context:nil];
NSLog(@"height = %f", paragraphRect.size.height);
if (paragraphRect.size.height<200) {
cell.btnMore.hidden = YES;
}
else{
cell.btnMore.hidden = NO;
}
cell.btnMore.tag = indexPath.row;
return cell;
}
// action of button click
-(IBAction)MoreBtnClicked:(id)sender {
if (!isReadMoreButtonTouched) {
isReadMoreButtonTouched = YES;
}
else{
isReadMoreButtonTouched = NO;
}
indexOfReadMoreButton = [sender tag];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[sender tag] inSection:0];
[self.tblKB reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; //reload that cell of your tableview
}
Upvotes: 0
Reputation: 5660
Anyhow need to get reference of the cell and indexPath on which the button is tapped in your myAction()
.
Create a private variable CGFloat newCellHeight;
and initialize it to 0.0.
Let reference to the associated cell is selectedCell
and selected index path is indexPathOfTappedCell
.
- (void)myAction{
UILabel *descLabel = (UILabel*)[selectedCell.contentView viewWithTag:4];
[descLabel sizeToFit]; // Automatically increases the height of the label as required
newCellHeight = CGRectGetMaxY(descLabel.frame) + 10.0; // Extra padding 10.0
[tableView reloadRowsAtIndexPaths:@[indexPathOfTappedCell] withRowAnimation:UITableViewRowAnimationAutomatic];
}
Now add the following TableView delegate method in your view controller
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (indexPath.section == indexPathOfTappedCell.section &&
indexPath.row == indexPathOfTappedCell.row ) {
return newCellHeight;
}
return 44.0; // Suppose default height is 44.0
}
Upvotes: 0
Reputation: 5380
First of all it is not a good practice to build cell in cellForRowAtIndexPath
. Use willDisplayCell
instead. See here why.
Secondly to do what you want you have to set desired height in heightForRowAtIndexPath
. Once this accomplished, within your button selector call to refresh specific cells using
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPathOfYourCell, nil] withRowAnimation:UITableViewRowAnimationAutomatic];
The implementation is similar:
- (void)buttonSelector
{
myLabel.text = @"YOUR TEXT";
[myLabel sizeToFit];
[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPathOfYourCell, nil] withRowAnimation:UITableViewRowAnimationAutomatic];
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
...
return yourLabel.height;
}
Upvotes: 1