0

I have a TableViewController with Prototype Cells that look like this: enter image description here

I would like to only display the Title and Date labels by default when the TableView data loads. Additionally, when the user selects a particular cell, I want the cell to expand so that the user can read the contents of the Description label (which can run over multiple lines).

I have looked through several sources on StackOverflow including the following: https://stackoverflow.com/a/3075493/4481169.

Most of the sources I have looked through assume that when the cell is not selected it will return to a specific height. However, the text of my Title label can take up multiple lines in some cases which means that each cell will have a different initial row height to begin with.

How can I make it so when the user selects a particular cell it expands to display all three labels and when that cell is unselected, the cell reverts to its original height?

Community
  • 1
  • 1
Iavor
  • 1,997
  • 16
  • 27

2 Answers2

1

Probably the easiest way to achieve this would be having 2 cell prototypes for:

  1. Not selected: with 2 UILabels; // let is be with ID: @"NotSelectedCell"
  2. Selected: with all 3 UILabels; // @"SelectedCell"

Also You need to store the indexPath of the selected cell, so:

@implementation InformationTableViewController {
    NSIndexPath* selectedCellIndexPath;
}

In your tableView delegate method tableView:cellForRowAtIndexPath: you need to switch between NotSelectedCell and SelectedCell according to the indexPath:

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

    if ([indexPath isEqual:selectedCellIndexPath]) {
        NSString* cellIdentifier = @"SelectedCell";
        InformationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellIdentifier forIndexPath:indexPath];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        if (cell == nil) {
            cell = [[InformationTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
            cell.accessoryType = UITableViewCellAccessoryNone;
        }
        cell.title = // title
        cell.date  = // date
        cell.description = // description

        return cell;
    }
    else {
        NSString* cellIdentifier = @"NotSelectedCell";
        InformationTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: cellIdentifier forIndexPath:indexPath];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
        if (cell == nil) {
            cell = [[InformationTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier];
                cell.accessoryType = UITableViewCellAccessoryNone;
        }
        cell.title = // title
        cell.date  = // date

        return cell;
    }
}

Also you must save a new indexPath everytime user selects a new cell and reload the tableView:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    selectedCellIndexPath = [indexPath copy];
    [self.tableView reloadData];
}

In order to recover the scroll position of the tableView before reload, you have to do the following:

CGFloat tableViewContentHeight = self.tableView.contentSize.height;
[self.tableView reloadData];
CGFloat newTableViewContentHeight = self.tableView.contentSize.height;
self.tableView.contentOffset = CGPointMake(0, newTableViewContentHeight - tableViewContentHeight);
Roman Slyepko
  • 1,393
  • 2
  • 8
  • 15
  • Thanks Roman, I tried this out and it worked. Is there any way to animate the change of prototype cell? Also, how can I keep the selected cell highlighted? – Iavor Mar 27 '16 at 07:45
  • @ivdekov 1. You can use [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade] to animate reloading of the tableView; 2. In order to highlight the selected cell you can set a backgroundColor for the SelectedCell prototype. Please consider accepting the answer if it's the solution to your problem – Roman Slyepko Mar 27 '16 at 11:47
  • Thanks for your answer. In my didSelectRowAtIndexPath method, I create an array of IndexPaths and store my currently selected IndexPath and my previously selected IndexPath. I then call tableView.reloadRowsAtIndexPaths and pass in the array of IndexPaths. Then, in my cellForRowAtIndexPath method, if the indexPath == currently selected index path, I change the cell's background color. Is it okay to do it this way? – Iavor Mar 27 '16 at 15:49
  • When I select the rows at the bottom of the TableView, the screen scrolls up. Do you know how I can prevent this? – Iavor Mar 27 '16 at 15:50
  • @ivdekov updated the answer; Actually you can't prevent scrolling up, so you have to scroll back down to the previous position – Roman Slyepko Mar 27 '16 at 16:53
  • replace `[self.tableView reloadData]` with `[self.tableView beginUpdates]; [self.tableView endUpdates];` to animate the change and also prevent the scroll up. – Sulthan Mar 27 '16 at 17:04
  • @Roman Slyepko I ended up using the method `tableView.scrollToRowAtIndexPath` to scroll the tableView to the correct position after reloading the appropriate cells. Thank you for all your help :) – Iavor Mar 27 '16 at 17:05
  • @Sulthan I tried replacing the `tableView.reloadRowsAtIndexPaths` method with `tableView.beginUpdates()` followed by `tableView.endUpdates()` but the description does not show up. The cell gets highlighted but nothing happens. – Iavor Mar 27 '16 at 17:09
0

For your requirement i would suggest you to do this steps

  • First of don't give height constraint to description and even don't add any text in it i.e keep it blank
  • Then when you get the values for description store in other array
  • After this on delegate method for didselectrowatindex you can fill the value of that description and it reload it .

  • So it will fill the text in description and take the height as required

Moin Shirazi
  • 4,372
  • 2
  • 26
  • 38
  • Thanks for your response Moin. I tried implementing you solution and it works but there are glitches. When I click on the cells at the bottom of the TableView the whole table view scrolls upwards a bit. – Iavor Mar 27 '16 at 07:26
  • It will scroll up as the description label is open and so it moves up – Moin Shirazi Mar 27 '16 at 07:28
  • if u find the answer helpful then please accept it so even other developers like us can get help from. Thank u – Moin Shirazi Mar 27 '16 at 09:19