el-flor
el-flor

Reputation: 1476

iOS - Reuse exact same cell design and code in multiple views

I have 4 different views in my app that currently display the exact same UITableViewCell. In my Storyboard I have 4 occurrences of the same cell (which is quite a complicated custom cell) and in the .m files, I have more or less the exact same code do associate the data to the UITableViewCell.

I know this is a wrong approach -- it's extremely hard to maintain and to update.

What is the right approach to centralise the UITableViewCell in the Storyboard and the centralise the code that populate the table so I can reuse it in different views?

Upvotes: 3

Views: 700

Answers (2)

Wolfgang Schreurs
Wolfgang Schreurs

Reputation: 11834

Personally I think writing all views in code is the best way to reach maximum reusability (and extensibility, since nib files can't be subclassed). But I think you might also be able to create a separate nib for the UITableViewCell and load it in each view controller. I think for either approach (designing the cell fully in code, or with help of a nib file) you would load the cell in code in viewDidLoad, using something like:

[self.tableView registerClass:MyCustomCell.class forCellReuseIdentifier:@"Cell"];

The above is what I mostly use, since I like to write all views in code, apparently for loading nibs you can refer to the method described by dirtydanee.

Your tableView would then load the cell with the same identifier in -cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];

    // configure your cell here ...

    return cell;
}

Upvotes: 5

dirtydanee
dirtydanee

Reputation: 6151

I would recommend to create a Xib file for your UITableViewCell subclass, with a configuration(_:) function declared on it. This function can take any parameter, for example a dictionary. However, you can feed a specific data model holding your parameters, a struct maybe or whatever data type you are using.

ReusableTableViewCell.h

#import <UIKit/UIKit.h>

@interface ReusableTableViewCell: UITableViewCell 
@property(nonatomic, weak) IBOutlet UILabel* title;
@property(nonatomic, weak) IBOutlet UILabel* subTitle;

/// - Parameter configuration: It is a dictionary at the minute
///                            However, it could be any type, you could even be creating your own model struct or class
- (void)configureWith:(NSDictionary *)configuration;
@end

ReusableTableViewCell.m

#import "ReusableTableViewCell.h"

@implementation ReusableTableViewCell

- (void)configureWith:(NSDictionary *)configuration {
    self.title.text = configuration[@"title"];
    self.subTitle.text = configuration[@"subTitle"];
}

- (void)prepareForReuse {
    [super prepareForReuse];
    self.title.text = nil;
    self.subTitle.text = nil;
}

@end

Register the nib to your tableView. Important, do not register it as a class, register it as a nib.

[tableView registerNib: [UINib nibWithNibName:@"yourCellNibName" bundle:nil] forCellReuseIdentifier:@"yourReuseIdentifier"];

And at the end in your cellForRowAtIndexPath just simply get the configuration and feed it into your tableViewCell.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    // create your cell
    ReusableTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"yourReuseIdentifier"];
    // get your configuration
    NSDictionary *configuration = [configurations objectAtIndex:indexPath.row];

    //configure your cell
    [cell configureWith: configuration];
    return cell;
}

Upvotes: 4

Related Questions