Permalink
Browse files

Because the table view data source methods only referred to the table…

… model

and the cell provider, the table model can become the data source directly.

A table view controller still acts as the table-view's delegate as that mostly
relates to user-event handling but all it has to do now is implement the
LRTableModelCellProvider and LRTableModelEventListener methods.
  • Loading branch information...
1 parent be9aa0f commit 2e9e17e5b81b49e4b3cdd615c53687d4df2336d1 @lukeredpath committed Aug 10, 2010
View
@@ -8,9 +8,11 @@
#import <Foundation/Foundation.h>
#import "LRTableModelEventListener.h"
+#import "LRTableModelCellProvider.h"
-@protocol LRTableModel
+@protocol LRTableModel <UITableViewDataSource>
+- (id)initWithCellProvider:(id<LRTableModelCellProvider>)theCellProvider;
- (NSInteger)numberOfSections;
- (NSInteger)numberOfRows;
- (id)objectAtIndexPath:(NSIndexPath *)indexPath;
@@ -9,7 +9,7 @@
#import <UIKit/UIKit.h>
-@protocol LRTableModelCellProvider
+@protocol LRTableModelCellProvider <NSObject>
- (NSString *)cellReuseIdentifierForIndexPath:(NSIndexPath *)indexPath;
- (UITableViewCell *)cellForObjectAtIndexPath:(NSIndexPath *)indexPath reuseIdentifier:(NSString *)reuseIdentifier;
View
@@ -15,17 +15,19 @@ - (void)notifyListeners:(LRTableModelEvent *)event;
@implementation SimpleTableModel
-- (id)init
+- (id)initWithCellProvider:(id<LRTableModelCellProvider>)theCellProvider;
{
if (self = [super init]) {
objects = [[NSMutableArray alloc] init];
eventListeners = [[NSMutableArray alloc] init];
+ cellProvider = [theCellProvider retain];
}
return self;
}
- (void)dealloc
{
+ [cellProvider release];
[eventListeners release];
[objects release];
[super dealloc];
@@ -92,4 +94,30 @@ - (void)notifyListeners:(LRTableModelEvent *)event;
}
}
+#pragma mark -
+#pragma mark UITableViewDataSource methods
+
+- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
+{
+ NSString *reuseIdentifier = [cellProvider cellReuseIdentifierForIndexPath:indexPath];
+
+ UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
+ if (cell == nil) {
+ cell = [cellProvider cellForObjectAtIndexPath:indexPath reuseIdentifier:reuseIdentifier];
+ }
+ [cellProvider configureCell:cell forObject:[self objectAtIndexPath:indexPath] atIndexPath:indexPath];
+
+ return cell;
+}
+
+- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
+{
+ return [self numberOfSections];
+}
+
+- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
+{
+ return [self numberOfRows];
+}
+
@end
@@ -7,13 +7,14 @@
//
#import <UIKit/UIKit.h>
+
#import "LRTableModelEventListener.h"
#import "LRTableModelCellProvider.h"
@class SimpleTableModel;
@interface SimpleTableViewController : UITableViewController <LRTableModelEventListener, LRTableModelCellProvider> {
SimpleTableModel *tableModel;
- id<LRTableModelCellProvider> cellProvider;
}
+@property (nonatomic, readonly) SimpleTableModel *tableModel;
@end
@@ -12,36 +12,47 @@
@implementation SimpleTableViewController
+NSArray *plistData()
+{
+ return [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"repositories" ofType:@"plist"]];
+}
+
- (void)dealloc
{
[tableModel release];
[super dealloc];
}
+- (SimpleTableModel *)tableModel
+{
+ if (tableModel == nil) {
+ tableModel = [[SimpleTableModel alloc] initWithCellProvider:self];
+ [tableModel addTableModelListener:self];
+ }
+ return tableModel;
+}
+
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"Simple Table View";
self.tableView.rowHeight = 65;
-
- tableModel = [[SimpleTableModel alloc] init];
- [tableModel addTableModelListener:self];
-
- cellProvider = self;
-
- NSArray *repositoriesFromPlist = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"repositories" ofType:@"plist"]];
+ self.tableView.dataSource = self.tableModel;
NSMutableArray *objects = [NSMutableArray array];
- [repositoriesFromPlist enumerateObjectsUsingBlock:^(id repository, NSUInteger idx, BOOL *stop) {
+ [plistData() enumerateObjectsUsingBlock:^(id repository, NSUInteger idx, BOOL *stop) {
SimpleObject *object = [[SimpleObject alloc] initWithTitle:[repository objectForKey:@"name"] description:[repository objectForKey:@"description"]];
[objects addObject:object];
[object release];
}];
- [tableModel setObjects:objects];
+ [self.tableModel setObjects:objects];
}
+#pragma mark -
+#pragma mark LRTableModelEventListener methods
+
- (void)tableModelChanged:(LRTableModelEvent *)changeEvent
{
switch (changeEvent.type) {
@@ -54,6 +65,9 @@ - (void)tableModelChanged:(LRTableModelEvent *)changeEvent
}
}
+#pragma mark -
+#pragma mark LRTableModelCellProvider methods
+
- (NSString *)cellReuseIdentifierForIndexPath:(NSIndexPath *)indexPath;
{
static NSString *identifier = @"CellIdentifier";
@@ -74,29 +88,4 @@ - (void)configureCell:(UITableViewCell *)cell forObject:(id)object atIndexPath:(
cell.detailTextLabel.text = simpleObject.description;
}
-#pragma mark Table View Methods
-
-- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-{
- NSString *reuseIdentifier = [cellProvider cellReuseIdentifierForIndexPath:indexPath];
-
- UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:reuseIdentifier];
- if (cell == nil) {
- cell = [cellProvider cellForObjectAtIndexPath:indexPath reuseIdentifier:reuseIdentifier];
- }
- [cellProvider configureCell:cell forObject:[tableModel objectAtIndexPath:indexPath] atIndexPath:indexPath];
-
- return cell;
-}
-
-- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
-{
- return [tableModel numberOfSections];
-}
-
-- (NSInteger)tableView:(UITableView *)table numberOfRowsInSection:(NSInteger)section
-{
- return [tableModel numberOfRows];
-}
-
@end
@@ -48,7 +48,7 @@ id refreshEvent() {
__block LRMockery *context = [[LRMockery mockeryForTestCase:self] retain];
beforeEach(^{
- model = [[SimpleTableModel alloc] init];
+ model = [[SimpleTableModel alloc] initWithCellProvider:nil];
});
context(@"with a single object", ^{

0 comments on commit 2e9e17e

Please sign in to comment.