Skip to content

TLIndexPathTools makes it easy to build rich, dynamic table and collection views on iOS.

Notifications You must be signed in to change notification settings

sarobear/TLIndexPathTools

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

94 Commits
 
 
 
 
 
 
 
 

Repository files navigation

TLIndexPathTools

TLIndexPathTools is a set of components designed to greatly simplify the building of rich, dynamic table and collection views. Some awesome things you can do with TLIndexPathTools include:

  • Automatically calculate and perform animated batch updates
  • Perform animated sorting and filtering operations against an array or NSFetchRequest
  • Easily manage multiple cell prototypes and/or multiple data types as the data model changes

The central component of TLIndexPathTools is the TLIndexPathController class. This class is a lot like Core Data's NSFetchedResultsController class in that it is responsible for tracking a data source and reporting changes to the client. The big difference is that, while TLIndexPathController does support NSFetchRequest, it does not require Core Data at all. TLIndexPathController can just as easily work with an array of strings. For example, you can initialize a TLIndexPathController with an array of strings to display as table rows and then give the controller a new array of strings (perhaps a filtered or sorted version of the original array) and the table will automatically animate to the new state. See the "Shuffle" example project.

TLIndexPathTools provides base view controller classes TLTableViewController and TLCollectionViewController (for table and collection views, respectively) that implement the essential delegate methods to get you up-and-running as quickly as possible.

Installation

  1. Download the TLIndexPathTools project
  2. Add the TLIndexPathTools sub-folder (sibling of the Examples folder) to your Xcode project.
  3. Link to QuartzCore.framework and CoreData.framework (on the Build Phases tab of your project's target).

Getting Started

The basic usage is as follows:

#import <UIKit/UIKit.h>
#import "TLIndexPathController.h"
@interface ViewController : TLTableViewController
@end

#import "ViewController.h"
@implementation ViewController

- (void)viewDidLoad
{
	[super viewDidLoad];
	self.indexPathController.items = @[@"Chevrolet", @"Bubble Gum", @"Chalkboard"]];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
	UITableViewCell *cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
	NSString *title = [self.indexPathController.dataModel itemAtIndexPath:indexPath];
	cell.textLabel.text = title;
	return cell;
}

This yields a table view with rows "Chevrolet", "Bubble Gum" and "Chalkboard". Note that by default, as in this example, TLIndexPathTools assumes the cell's reuse identifier is "Cell".

Things get interesting when we add dynamic behavior, such as a method that shuffles rows (which we can wire into a button):

- (IBAction)shuffle
{
    NSMutableArray *shuffledItems = [NSMutableArray arrayWithArray:self.indexPathController.items];
    NSInteger count = shuffledItems.count;
    for (int i = 0; i < count; i++) {
        [shuffledItems exchangeObjectAtIndex:i withObjectAtIndex:arc4random() % count];
    }
    self.indexPathController.items = shuffledItems;
}

Thats all it takes to generate a nice, smooth animated shuffle effect. Try running the Shuffle sample project to see the same effect in action with a UICollectionView.

Now, lets pull back the curtain a bit and see what this looks like without the help of TLTableViewController. Here is what the app looks like when done as a direct subclass of UITableViewController (unchanged lines are gray):

#import <UIKit/UIKit.h>
#import "TLIndexPathController.h"
@interface ViewController : UITableViewController
@property (strong, nonatomic) TLIndexPathController *indexPathController;
@end

#import "ViewController.h"
@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.indexPathController = [[TLIndexPathController alloc] init];
	self.indexPathController.items = @[@"Chevrolet", @"Bubble Gum", @"Chalkboard"]];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return self.indexPathController.dataModel.numberOfSections;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [self.indexPathController.dataModel numberOfRowsInSection:section];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    NSString *title = [self.indexPathController.dataModel itemAtIndexPath:indexPath];
    cell.textLabel.text = title;
    return cell;
}

- (IBAction)shuffle
{
    NSMutableArray *shuffledItems = [NSMutableArray arrayWithArray:self.indexPathController.items];
    NSInteger count = shuffledItems.count;
    for (int i = 0; i < count; i++) {
        [shuffledItems exchangeObjectAtIndex:i withObjectAtIndex:arc4random() % count];
    }
    self.indexPathController.items = shuffledItems;
}

#pragma mark - TLIndexPathControllerDelegate

- (void)controller:(TLIndexPathController *)controller didUpdateDataModel:(TLIndexPathUpdates *)updates
{
    [updates performBatchUpdatesOnTableView:self.tableView withRowAnimation:UITableViewRowAnimationFade];    
}

@end

As you can see, TLTableViewController is just adding some simple boiler plate methods. It is completely fine to not use TLTableViewController or TLCollectionViewController, though the former does provide some nice bells and whistles like automatic (dynamic) row height calculations (see the Dynamic Height sample project).

Now lets step through the code for a brief introduction to some basic APIs.

###TLIndexPathController

@interface ViewController : UITableViewController
@property (strong, nonatomic) TLIndexPathController *indexPathController;
@end

TLIndexPathController is the primary API access point, so we have a public property to get or set a controller. If you're familiar with Core Data's NSFetchedResultsController, TLIndexPathController plays a similar role except that it work with regular arrays. It also works with Core Data and can do things that NSFetchedResultsController can't do, such as animated sorting and filtering (more on that later).

Both TLTableViewController and TLCollectionViewController provide default index path controllers, but it is normal to replace this instance with a custom one (see the selection of initializers in TLIndexPathController.h).

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.indexPathController = [[TLIndexPathController alloc] init];
	self.indexPathController.items = @[@"Chevrolet", @"Bubble Gum", @"Chalkboard"]];
}

Here we create a default index path controller just as TLTableViewController does. Then we populate the controller with our data by setting the items array property. Data items can be any type of object from NSStrings as we have here to NSDictionaries (see the JSON sample project) to NSManagedObjects (see the Core Data sample project).

###TLIndexPathDataModel

TODO...

About

TLIndexPathTools makes it easy to build rich, dynamic table and collection views on iOS.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published