Skip to content

Instantly share code, notes, and snippets.

@lobianco
Created September 24, 2016 20:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lobianco/106a03391a01ccec4e0cc1e6b8277e5f to your computer and use it in GitHub Desktop.
Save lobianco/106a03391a01ccec4e0cc1e6b8277e5f to your computer and use it in GitHub Desktop.
ALTableViewThing keeps track of table view rows and sections for you.
//
// ALTableViewThing.h
//
// Created by Anthony Lobianco.
// Copyright © 2016 All rights reserved.
//
#import <Foundation/Foundation.h>
// to make it easier for outside classes to know which values to cast to
// their specific enum type
//
typedef NSUInteger ALTableViewThingCastableInteger;
@class ALTableViewThing;
@protocol ALTableViewThingDelegate <NSObject>
/**
* The maximum possible number of rows in a section (e.g.
* ALTableViewFirstSectionRowsCount).
*
* @param section The row's section.
*
* @return The maximum number of rows.
*/
- (NSUInteger)tableViewThing:(ALTableViewThing *)thing maxNumberOfRowsInSection:(NSUInteger)section;
@optional
/**
* The maximum possible number of sections (e.g. ALTableViewSectionsCount).
*
* @return The maximum number of sections. 1 if unimplemented.
*/
- (NSUInteger)tableViewThingMaxNumberOfSections:(ALTableViewThing *)thing;
/**
* Conditionally show or hide certain sections.
*
* @param section The section to show/hide.
*
* @return A bool. YES if unimplemented.
*/
- (BOOL)tableViewThing:(ALTableViewThing *)thing shouldShowSection:(NSUInteger)section;
/**
* Conditionally show or hide certain rows in a section.
*
* @param row The row to show/hide.
* @param section The row's section.
*
* @return A bool. YES if unimplemented.
*/
- (BOOL)tableViewThing:(ALTableViewThing *)thing
shouldShowRow:(NSUInteger)row
inSection:(NSUInteger)section;
@end
@interface ALTableViewThing : NSObject
@property (nonatomic, weak) id<ALTableViewThingDelegate> delegate;
/**
* An array of NSNumbers that corresponds to the non-hidden sections
* based on the delegate methods above. The values can be mapped directly
* to your specific enum type.
*
* @return An array of NSNumbers.
*/
- (NSArray <NSNumber *> *)sections;
/**
* Call this method in your tableView's `numberOfSections` delegate method.
*
* @return The number of sections. This will NOT always be equal to sections.count.
*/
- (NSUInteger)numberOfSections;
/**
* An array of NSNumbers that corresponds to the non-hidden rows in a
* section based on the delegate methods above. The values can be mapped
* directly to your specific enum type.
*
* @param section The row's section.
*
* @return An array of NSNumbers.
*/
- (NSArray <NSNumber *> *)rowsInSection:(NSUInteger)section;
/**
* Call this method in your tableView's `numberOfRowsInSection:` delegate method.
*
* @param section The row's section.
*
* @return The number of rows. This WILL always be equal to rowsInSection:.count.
*/
- (NSUInteger)numberOfRowsInSection:(NSUInteger)section;
/**
* Use this method to map a row's value to its enum value
* based on any conditionally hidden rows.
*
* @param row The row to adjust.
* @param section The row's section.
*
* @return The adjusted row value. Cast it to your specific enum type.
*/
- (ALTableViewThingCastableInteger)enumForRow:(NSUInteger)row inSection:(NSUInteger)section;
/**
* Use this method to map an enum value to a table view row
* based on any conditionally hidden rows.
*
* @param enumVal The enum value
* @param section The enum's section.
*
* @return The enum value's row number in the table view.
*/
- (NSUInteger)rowForEnum:(ALTableViewThingCastableInteger)enumVal inSection:(NSUInteger)section;
@end
//
// ALTableViewThing.m
//
// Created by Anthony Lobianco.
// Copyright © 2016 All rights reserved.
//
#import "ALTableViewThing.h"
@implementation ALTableViewThing
- (NSArray<NSNumber *> *)sections
{
NSUInteger maxNumberOfSections = [self maxNumberOfSections];
NSMutableArray<NSNumber *> *sections = [[NSMutableArray alloc] init];
for (NSUInteger i = 0; i < maxNumberOfSections; i++)
{
if ([self shouldShowSection:i])
{
[sections addObject:@(i)];
}
}
return [sections copy];
}
- (NSUInteger)numberOfSections
{
// always return count of ALL sections, even if the delegate says a
// certain section should be hidden. in that case, we'll return 0 rows
// for that specific section.
//
return [self maxNumberOfSections];
}
- (NSArray<NSNumber *> *)rowsInSection:(NSUInteger)section
{
if (![self shouldShowSection:section])
{
return 0;
}
NSUInteger maxNumberOfRows = [self.delegate tableViewThing:self maxNumberOfRowsInSection:section];
NSMutableArray<NSNumber *> *rows = [[NSMutableArray alloc] init];
for (NSUInteger i = 0; i < maxNumberOfRows; i++)
{
if ([self shouldShowRow:i inSection:section])
{
[rows addObject:@(i)];
}
}
return [rows copy];
}
- (NSUInteger)numberOfRowsInSection:(NSUInteger)section
{
return [self rowsInSection:section].count;
}
- (ALTableViewThingCastableInteger)enumForRow:(NSUInteger)row inSection:(NSUInteger)section
{
NSParameterAssert([self shouldShowSection:section]);
return [[self rowsInSection:section][row] integerValue];
}
- (NSUInteger)rowForEnum:(ALTableViewThingCastableInteger)enumVal inSection:(NSUInteger)section
{
NSParameterAssert([self shouldShowSection:section]);
NSUInteger numberOfRows = [self numberOfRowsInSection:section];
NSUInteger finalEnumVal = numberOfRows;
for (NSInteger i = (numberOfRows - 1); i >= 0; i--)
{
if (enumVal > [self enumForRow:i inSection:section])
{
break;
}
finalEnumVal = i;
}
return finalEnumVal;
}
#pragma mark - Internal methods
- (NSUInteger)maxNumberOfSections
{
if ([self.delegate respondsToSelector:@selector(tableViewThingMaxNumberOfSections:)])
{
return [self.delegate tableViewThingMaxNumberOfSections:self];
}
return 1;
}
- (BOOL)shouldShowSection:(NSUInteger)section
{
if ([self.delegate respondsToSelector:@selector(tableViewThing:shouldShowSection:)])
{
return [self.delegate tableViewThing:self shouldShowSection:section];
}
return YES;
}
- (BOOL)shouldShowRow:(NSUInteger)row inSection:(NSUInteger)section
{
if ([self.delegate respondsToSelector:@selector(tableViewThing:shouldShowRow:inSection:)])
{
return [self.delegate tableViewThing:self shouldShowRow:row inSection:section];
}
return YES;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment