Monday, April 12, 2010

List Creation: Creating from a set.

Creating a list based on a set



Instead of using a fetched data controller, sometimes it's nice to take a set or are and display the contents of that array.  This is a reference directly supported by the core data, it reveals items 'related' to your current one in a set.   I was already using this for sight word display and editing.

The goal is to expand my list controller so that I can take in a set, and operate on it.  The usage will be:


- (IBAction) editList:(id) sender
{

JLTableContainer *container=
[JLTableContainer createSetController:nil forList:currentWordList.containedWords
  sortKey:@"wordName"   inContext:[SightWordState Instance].control.managedObjectContext 
controlledBy:nil];
UISelectionMaster * selector=[[UISelectionMaster alloc] init];
selector.listToSelect=container;
[self.navigationController pushViewController:selector animated:true];
}

In this case, I'm just creating a table that displays the 'contained words' set.  The rest of my logic is the same, and I can even decorate it with a selector in the same fashion as my FetchedController table display.  

The implementation is fairly simple given the above:

Initializing the container


First I expand a routine that creates the container, and initializes it.  This needs some refactoring with the other API creation routines, but for now I'll leave it alone.
+ (JLTableContainer*) createSetController:(UITableView *)table
forList:(NSSet *) setToUse
  sortKey:(NSString *) key
  inContext:(NSManagedObjectContext *) context
controlledBy:(NSObject<JLTableController>*) controller
{
JLTableContainer *returnValue=[[JLTableContainer alloc]init];
SimpleDescriptionCellProvider *simpleCellProvider=[[SimpleDescriptionCellProvider alloc] init];

returnValue.table=table;
JLSetSource *source=[[JLSetSource alloc] initWithSet:setToUse sortKey:key];
source.fetchContext=context;
JLStandardCallbackHandler *callHandler=[[JLStandardCallbackHandler alloc]init];
returnValue.tableController=controller;
returnValue.cellProvider=simpleCellProvider;
returnValue.tableSource=source;
returnValue.callbackHandler=callHandler;
[returnValue connectObjects];
return [returnValue autorelease];
}


The header file for the data source


This is the definition of a table source that has a 'set' (converted to a sorted array) as a backing store.  Note that it currently does not support reloading.  This will have to be added.
#import "JLTableControl.h"

@interface JLSetSource : NSObject {
id<JLCellProvider> cellProvider;
NSSet *set;
UITableView *table;
NSArray *currentList;
NSManagedObjectContext *fetchContext;
}
@property (retain,nonatomic) NSSet *set;
@property (retain,nonatomic) NSManagedObjectContext *fetchContext;
@property (retain,nonatomic) NSArray *currentList;
- (JLSetSource *) initWithSet:(NSSet*)set sortKey:(NSString*) sort;

@end


The source for the above




@implementation JLSetSource
@synthesize set;
@synthesize table;
@synthesize cellProvider;
@synthesize currentList;
@synthesize fetchContext;
- (JLSetSource*) initWithSet:(NSSet*)setToUse sortKey:(NSString*) sort
{
self.set=setToUse;
self.currentList=[setToUse getSortedArray:sort];
return self;  
 
}

// Standard section headers.
//- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
//    return [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles];
//}
// Get the cell for the current object.  Default to a simple description cell if no actual cell provider is created.
- (UITableViewCell *)tableView:(UITableView *)tableViewb cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (self.cellProvider==nil)
self.cellProvider=[[SimpleDescriptionCellProvider alloc] initWithIdentifier:@"GenericQueue"];
NSManagedObject *managedObject=[self.currentList objectAtIndex:indexPath.row];
if (managedObject !=nil)
{
  UITableViewCell *returnValue=[cellProvider cellForObject:managedObject atIndexPath:indexPath forTable:tableViewb];
return returnValue;
}
return nil;
}

- (NSInteger) numberOfSectionsInTableView:(UITableView*) tableView{
return 1;

}

- (id) objectAtIndexPath:(NSIndexPath *) path
{
return [self.currentList objectAtIndex:path.row];
}

// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.currentList count];
}

All in all its pretty straightforward stuff, but it's nice to have it isolated and implemented once.

No comments:

Post a Comment