Ghobs
Ghobs

Reputation: 859

How to create an extendable UITableView section?

Currently, each of my UITableView sections contains 10 rows. What I want is for each section to initialize those 10 rows, but only show 3. If a user taps a "show more" button, all 10 would then be shown. I thought about doing this by using something like this for the hiding part:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{    
    float heightForRow = 65;

    if(cell.tag>=3)
        return 0;
    else
        return heightForRow;
}

This is meant to take care of hiding all but the first 3 rows. The issue is that I get an error stating use of undeclared identifier 'cell'. I initialize cell in cellForRowAtIndexPath like so:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Initialize cell
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (!cell) {
        // if no cell could be dequeued create a new one
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }

    // No cell seperators = clean design
    tableView.separatorColor = [UIColor clearColor];

    // title of the item
    cell.textLabel.text = _matchCenterArray[indexPath.section][@"Top 3"][indexPath.row][@"Title"];
    cell.textLabel.font = [UIFont boldSystemFontOfSize:14];

    // price of the item
    cell.detailTextLabel.text = [NSString stringWithFormat:@"$%@", _matchCenterArray[indexPath.section][@"Top 3"][indexPath.row][@"Price"]];
    cell.detailTextLabel.textColor = [UIColor colorWithRed:0/255.0f green:127/255.0f blue:31/255.0f alpha:1.0f];

    // image of the item
    NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:_matchCenterArray[indexPath.section][@"Top 3"][indexPath.row][@"Image URL"]]];
    [[cell imageView] setImage:[UIImage imageWithData:imageData]];

    return cell;

}

How can I make cell accessible in heightForRowAtIndexPath?

Upvotes: 2

Views: 644

Answers (2)

E-Riddie
E-Riddie

Reputation: 14780

If you are OK with using 3rd Party Libraries here you have it:

SLExpandableTableView

Steps to implement it

Load the SLExpandableTableView in a UITableViewController

- (void)loadView
{
    self.tableView = [[SLExpandableTableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
}

Implement the SLExpandableTableViewDatasource protocol

- (BOOL)tableView:(SLExpandableTableView *)tableView canExpandSection:(NSInteger)section
{
    // return YES, if the section should be expandable
}

- (BOOL)tableView:(SLExpandableTableView *)tableView needsToDownloadDataForExpandableSection:(NSInteger)section
{
    // return YES, if you need to download data to expand this section. tableView will call tableView:downloadDataForExpandableSection: for this section
}

- (UITableViewCell<UIExpandingTableViewCell> *)tableView:(SLExpandableTableView *)tableView expandingCellForSection:(NSInteger)section
{
    // this cell will be displayed at IndexPath with section: section and row 0
}

Implement the SLExpandableTableViewDelegate protocol

- (void)tableView:(SLExpandableTableView *)tableView downloadDataForExpandableSection:(NSInteger)section
{
    // download your data here
    // call [tableView expandSection:section animated:YES]; if download was successful
    // call [tableView cancelDownloadInSection:section]; if your download was NOT successful
}

- (void)tableView:(SLExpandableTableView *)tableView didExpandSection:(NSUInteger)section animated:(BOOL)animated
{
  //...
}

- (void)tableView:(SLExpandableTableView *)tableView didCollapseSection:(NSUInteger)section animated:(BOOL)animated
{
  //...
}

Upvotes: 3

devgeek
devgeek

Reputation: 360

you could get each cell with

UITableViewCell* cell = [self.tableView cellForRowAtIndexPath:indexPath];

An alternative method, if the cells you want to show are the first 3 in order, instead of using cell.tag you could use

if (indexPath.row > 3 || self.hasPressedShowMoreButton){
return 0;
}

add a bool hasPressedShowMoreButton to the tableview class

and when they press the show more button you could have the button event handler set the bool and reload the tableview

-(IBAction)pressedShowMoreButton{
self.hasPressedShowMoreButton = YES;
[self.tableView reloadData];
}

which I think is a little cleaner than using the tags

In either case make sure you reload the table view when the user hits the show more button.

Upvotes: 1

Related Questions