Creating an UIViewController for similar functionalities
I have 3 UITableViewController:
CategoriesViewController
RecipesViewController
IngredientsViewController
They're ordered hierarchically. Below an example of the hierarchy:
Dessert (category)
Brownie (recipe)
Milk (ingredient)
Chocolate (ingredient)
Butter (ingredient)
Each one of these has similar functionalities with the others. For example
they all have sorting (moving rows), deleting, adding (presenting a modal
view) etc.
Currently I've repeated all the code for every view controller customizing
the parts that are related to each one. For example they all have an
instance variable like this:
CategoriesViewController.m:
@implementation CategoriesViewController {
NSMutableArray *categories;
}
RecipesViewController.m:
@implementation RecipesViewController {
NSMutableArray *recipes;
}
IngredientsViewController.m:
@implementation IngredientsViewController {
NSMutableArray *ingredients;
}
Because I think there's a better way to organize this view controller I've
tried to create a skeleton of MyListViewController.h:
@interface MyListViewController : UITableViewController
@property (nonatomic, strong) NSMutableArray *list;
@end
MyListViewController.m:
@implementation MyListViewController
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section
{
return [_list count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:@"ListCell"];
id currentObject = [_list objectAtIndex:indexPath.row];
cell.textLabel.text = [currentObject valueForKey:@"name"];
return cell;
}
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
// get item to delete
id object = [_list objectAtIndex:indexPath.row];
// remove it from list
[_list removeObjectAtIndex:indexPath.row];
// call callback
[self didFinishDeletingItem:object];
// delete row from tableview
[self.tableView deleteRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
}
}
- (void)didFinishDeletingItem:(id)item
{
}
In this way, once I've subclassed it I have only to assign list ivar to my
data structure. And I can even override methods like
didFinishDeletingItem: for customizing the behavior of each controller.
Because it's the first time that I would use best practices of writing and
organizing code in this way I would love to know your opinions AND which
are the best ways to abstract classes for reusing them following correctly
the DRY principle.
No comments:
Post a Comment