├── .gitattributes
├── IndexSet-Backed-Table
├── en.lproj
│ ├── InfoPlist.strings
│ ├── MainStoryboard_iPhone.storyboard
│ └── MainStoryboard_iPad.storyboard
├── Default.png
├── Default@2x.png
├── Default-568h@2x.png
├── SDAppDelegate.h
├── SDCalendarTableViewController.h
├── main.m
├── IndexSet-Backed-Table-Prefix.pch
├── SDDetailViewController.h
├── IndexSet-Backed-Table-Info.plist
├── SDDetailViewController.m
├── SDAppDelegate.m
└── SDCalendarTableViewController.m
├── IndexSet-Backed-Table.xcodeproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ │ └── Sean.xcuserdatad
│ │ ├── UserInterfaceState.xcuserstate
│ │ └── WorkspaceSettings.xcsettings
├── xcuserdata
│ └── Sean.xcuserdatad
│ │ ├── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── IndexSet-Backed-Table.xcscheme
│ │ └── xcdebugger
│ │ ├── Breakpoints.xcbkptlist
│ │ └── Breakpoints_v2.xcbkptlist
└── project.pbxproj
├── .gitignore
└── README.md
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.pbxproj binary merge=union
--------------------------------------------------------------------------------
/IndexSet-Backed-Table/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table/Default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/steam/IndexSet-Backed-Table/master/IndexSet-Backed-Table/Default.png
--------------------------------------------------------------------------------
/IndexSet-Backed-Table/Default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/steam/IndexSet-Backed-Table/master/IndexSet-Backed-Table/Default@2x.png
--------------------------------------------------------------------------------
/IndexSet-Backed-Table/Default-568h@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/steam/IndexSet-Backed-Table/master/IndexSet-Backed-Table/Default-568h@2x.png
--------------------------------------------------------------------------------
/IndexSet-Backed-Table.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table.xcodeproj/project.xcworkspace/xcuserdata/Sean.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/steam/IndexSet-Backed-Table/master/IndexSet-Backed-Table.xcodeproj/project.xcworkspace/xcuserdata/Sean.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/IndexSet-Backed-Table/SDAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // SDAppDelegate.h
3 | // IndexSet-Backed-Table
4 | //
5 | // Created by Sean Dougherty on 7/8/13.
6 |
7 | #import
8 |
9 | @interface SDAppDelegate : UIResponder
10 |
11 | @property (strong, nonatomic) UIWindow *window;
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table/SDCalendarTableViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SDCalendarTableViewController.h
3 | // IndexSet-Backed-Table
4 | //
5 | // Created by Sean Dougherty on 7/8/13.
6 |
7 | #import
8 |
9 | @class SDDetailViewController;
10 |
11 | @interface SDCalendarTableViewController : UITableViewController
12 |
13 | @property (strong, nonatomic) SDDetailViewController *detailViewController;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // IndexSet-Backed-Table
4 | //
5 | // Created by Sean on 7/8/13.
6 | // Copyright (c) 2013 Sean Dougherty. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "SDAppDelegate.h"
12 |
13 | int main(int argc, char *argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SDAppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table/IndexSet-Backed-Table-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header for all source files of the 'IndexSet-Backed-Table' target in the 'IndexSet-Backed-Table' project
3 | //
4 |
5 | #import
6 |
7 | #ifndef __IPHONE_5_0
8 | #warning "This project uses features only available in iOS SDK 5.0 and later."
9 | #endif
10 |
11 | #ifdef __OBJC__
12 | #import
13 | #import
14 | #endif
15 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table.xcodeproj/project.xcworkspace/xcuserdata/Sean.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges
6 |
7 | SnapshotAutomaticallyBeforeSignificantChanges
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X Finder
2 | .DS_Store
3 |
4 | # Xcode per-user config
5 | *.mode1
6 | *.mode1v3
7 | *.mode2v3
8 | *.perspective
9 | *.perspectivev3
10 | *.pbxuser
11 | xcuserdata
12 |
13 | # Build products
14 | build/
15 | *.o
16 | *.LinkFileList
17 | *.hmap
18 | Frank/frankified_build/
19 | test-reports/*
20 | *.ipa
21 | *.dSYM.zip
22 |
23 | # Automatic backup files
24 | *~.nib/
25 | *.swp
26 | *~
27 | *.dat
28 | *.dep
29 |
30 | # pods
31 | Pods/*
32 |
33 | # screenshots
34 | screenshots
35 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table/SDDetailViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // SDDetailViewController.h
3 | // IndexSet-Backed-Table
4 | //
5 | // Created by Sean Dougherty on 7/8/13.
6 |
7 | #import
8 |
9 | @interface SDDetailViewController : UIViewController
10 |
11 | @property (nonatomic, strong) NSDate *date;
12 | @property (nonatomic, weak) IBOutlet UILabel *dateLabel;
13 |
14 | // weakly held because the Calendar Table View holds onto it
15 | @property (nonatomic, weak) NSDateFormatter *dateFormatter;
16 |
17 |
18 | - (void)configureView;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table.xcodeproj/xcuserdata/Sean.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | IndexSet-Backed-Table.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 14373456178BA05700F0910D
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table.xcodeproj/xcuserdata/Sean.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table.xcodeproj/xcuserdata/Sean.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | IndexSet-Backed-Table
2 | =====================
3 |
4 | Example of a NSIndexSet backed UITableView for large sets of data. Super fast.
5 |
6 | Using an NSIndexSet, or a collection of NSIndexSets can be very fast. When your backing datasource for UITable is complex and quite large it often makes sense to ditch the first option of using an array to represent the table's model.
7 |
8 | While working on complex calendaring component for a client, Ryan Boyajian and I decided to take a different approach. Our problem was that we needed to display an unpredictable number of rows representing ranges of time over a large duration. Working with NSDate, NSDateFormatter and NSCalendar objects can be expensive. We needed to find a solution that minimized the number of date objects and calculations that were performed. We decided to go with NSIndexSets and the results surprised us. We saw drastically improved performance by drawing rows with indexes and delaying the expensive date calculations until they were needed.
9 |
10 | This project is not meant to be a plug and play component for use in your projects but rather an example that demonstrates the concepts behind using NSIndexSet(s) as your primary UITableView datasource. Checkout the blog post ##### for a more detailed discussion of the approach.
11 |
12 | First, a few disclaimers.
13 |
14 | 1. This is not production ready code. The goal of this example app is to demonstrate the speed of using NSIndexSets to represent the backing model of a UITableView. You should still follow best practices when making a real production app.
15 | 2. There are no unit tests, you should have unit tests. This example has no unit tests in order to stay focused on the example.
16 | 3. The UITableView controller subclass SDCalendarTableViewController is the datasource and delegate for the table. A production app should not be written this way. You should use a separate object as your datasource. Your code will be cleaner and easier to test.
17 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table/IndexSet-Backed-Table-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | com.seancdougherty.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UIMainStoryboardFile
28 | MainStoryboard_iPhone
29 | UIMainStoryboardFile~ipad
30 | MainStoryboard_iPad
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UIStatusBarTintParameters
36 |
37 | UINavigationBar
38 |
39 | Style
40 | UIBarStyleDefault
41 | Translucent
42 |
43 |
44 |
45 | UISupportedInterfaceOrientations
46 |
47 | UIInterfaceOrientationPortrait
48 | UIInterfaceOrientationLandscapeLeft
49 | UIInterfaceOrientationLandscapeRight
50 |
51 | UISupportedInterfaceOrientations~ipad
52 |
53 | UIInterfaceOrientationPortrait
54 | UIInterfaceOrientationPortraitUpsideDown
55 | UIInterfaceOrientationLandscapeLeft
56 | UIInterfaceOrientationLandscapeRight
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table/SDDetailViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // SDDetailViewController.m
3 | // IndexSet-Backed-Table
4 | //
5 | // Created by Sean Dougherty on 7/8/13.
6 |
7 | #import "SDDetailViewController.h"
8 |
9 | @interface SDDetailViewController ()
10 | @property (strong, nonatomic) UIPopoverController *masterPopoverController;
11 | @end
12 |
13 | @implementation SDDetailViewController
14 |
15 | #pragma mark - View Lifecycle
16 |
17 | - (void)viewDidLoad
18 | {
19 | [super viewDidLoad];
20 | [self configureView];
21 | }
22 |
23 |
24 | #pragma mark - Split view
25 |
26 | - (void)splitViewController:(UISplitViewController *)splitController
27 | willHideViewController:(UIViewController *)viewController
28 | withBarButtonItem:(UIBarButtonItem *)barButtonItem
29 | forPopoverController:(UIPopoverController *)popoverController
30 | {
31 | barButtonItem.title = NSLocalizedString(@"Days", @"Days");
32 | [self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
33 | self.masterPopoverController = popoverController;
34 | }
35 |
36 | - (void)splitViewController:(UISplitViewController *)splitController
37 | willShowViewController:(UIViewController *)viewController
38 | invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
39 | {
40 | [self.navigationItem setLeftBarButtonItem:nil animated:YES];
41 | self.masterPopoverController = nil;
42 | }
43 |
44 | #pragma mark - Public Mehtods
45 |
46 | - (void)configureView
47 | {
48 | if (self.date && self.dateFormatter)
49 | {
50 | self.dateFormatter.dateFormat = @"dd";
51 | self.dateLabel.text = [self.dateFormatter stringFromDate:self.date];
52 | self.dateFormatter.dateFormat = @"EEEE MMMM d, y";
53 | self.title = [self.dateFormatter stringFromDate:self.date];
54 | }
55 | }
56 |
57 | #pragma mark - Getters / Setters
58 |
59 | - (void)setDate:(NSDate *)date
60 | {
61 | if (_date != date)
62 | {
63 | _date = date;
64 | }
65 |
66 | if (self.masterPopoverController != nil)
67 | {
68 | [self.masterPopoverController dismissPopoverAnimated:YES];
69 | }
70 | }
71 |
72 | @end
73 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table/SDAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // SDAppDelegate.m
3 | // IndexSet-Backed-Table
4 | //
5 | // Created by Sean Dougherty on 7/8/13.
6 |
7 | #import "SDAppDelegate.h"
8 |
9 | @implementation SDAppDelegate
10 |
11 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
12 | {
13 | // Override point for customization after application launch.
14 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
15 | UISplitViewController *splitViewController = (UISplitViewController *)self.window.rootViewController;
16 | UINavigationController *navigationController = [splitViewController.viewControllers lastObject];
17 | splitViewController.delegate = (id)navigationController.topViewController;
18 | }
19 | return YES;
20 | }
21 |
22 | - (void)applicationWillResignActive:(UIApplication *)application
23 | {
24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application
29 | {
30 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
31 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
32 | }
33 |
34 | - (void)applicationWillEnterForeground:(UIApplication *)application
35 | {
36 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
37 | }
38 |
39 | - (void)applicationDidBecomeActive:(UIApplication *)application
40 | {
41 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
42 | }
43 |
44 | - (void)applicationWillTerminate:(UIApplication *)application
45 | {
46 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
47 | }
48 |
49 | @end
50 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table.xcodeproj/xcuserdata/Sean.xcuserdatad/xcschemes/IndexSet-Backed-Table.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
51 |
52 |
58 |
59 |
60 |
61 |
62 |
63 |
69 |
70 |
76 |
77 |
78 |
79 |
81 |
82 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table/SDCalendarTableViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // SDCalendarTableViewController.m
3 | // IndexSet-Backed-Table
4 | //
5 | // Created by Sean Dougherty on 7/8/13.
6 |
7 | #import "SDCalendarTableViewController.h"
8 | #import "SDDetailViewController.h"
9 |
10 | #define kNumberOfMonths 360
11 | #define kDayDateFormat @"EEE MMM d"
12 | #define kMonthDateFormat @"MMMM y"
13 |
14 | @interface SDCalendarTableViewController ()
15 | @property(nonatomic, strong) NSIndexSet *days;
16 | @property(nonatomic, strong) NSDate *beginningOfThisMonth;
17 | @property(nonatomic, strong) NSDateFormatter *formatter;
18 | @property(nonatomic, strong) NSDateFormatter *detailFormatter;
19 | @property(nonatomic, strong) NSDateComponents *components;
20 | @property(nonatomic, strong) NSDateComponents *components2;
21 | @end
22 |
23 | @implementation SDCalendarTableViewController
24 |
25 | - (void)awakeFromNib
26 | {
27 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
28 | {
29 | self.clearsSelectionOnViewWillAppear = NO;
30 | self.contentSizeForViewInPopover = CGSizeMake(320.0, 600.0);
31 | }
32 | [super awakeFromNib];
33 | }
34 |
35 | - (void)viewDidLoad
36 | {
37 | [super viewDidLoad];
38 |
39 | self.title = NSLocalizedString(@"30 Years of Days", @"30 Years of Days");
40 |
41 | // date formatter i.e. "Mon Jul 08, 2013"
42 | self.formatter = [[NSDateFormatter alloc] init];
43 | self.formatter.timeZone = [NSTimeZone localTimeZone];
44 | self.formatter.dateFormat = @"EEE MMM dd, y";
45 |
46 | // use a single date formatter for details to save on overhead, date formatters are expensive
47 | self.detailFormatter = [[NSDateFormatter alloc] init];
48 | self.detailFormatter.timeZone = [NSTimeZone localTimeZone];
49 |
50 | // date components for day incrementing
51 | self.components = [[NSCalendar currentCalendar] components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:[NSDate date]];
52 | self.components.day = 1;
53 |
54 | // beginningOfThisMonth, the only date created at launch (dates are created as needed)
55 | self.beginningOfThisMonth = [[NSCalendar currentCalendar] dateFromComponents:self.components];
56 |
57 | // reset the date components
58 | self.components = [[NSDateComponents alloc] init];
59 |
60 | self.detailViewController = (SDDetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
61 | }
62 |
63 |
64 | #pragma mark - Table View
65 |
66 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
67 | {
68 | return kNumberOfMonths;
69 | }
70 |
71 | - (NSInteger)tableView:(UITableView *)tableView
72 | numberOfRowsInSection:(NSInteger)section
73 | {
74 | return [self numberOfDaysInSection:section];
75 | }
76 |
77 | - (NSString *)tableView:(UITableView *)tableView
78 | titleForHeaderInSection:(NSInteger)section
79 | {
80 | self.formatter.dateFormat = kMonthDateFormat;
81 | return [self.formatter stringFromDate:[self dateForIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]]];
82 | }
83 |
84 | - (UITableViewCell *)tableView:(UITableView *)tableView
85 | cellForRowAtIndexPath:(NSIndexPath *)indexPath
86 | {
87 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
88 | self.formatter.dateFormat = kDayDateFormat;
89 | cell.textLabel.text = [self.formatter stringFromDate:[self dateForIndexPath:indexPath]];
90 | return cell;
91 | }
92 |
93 | - (void)tableView:(UITableView *)tableView
94 | didSelectRowAtIndexPath:(NSIndexPath *)indexPath
95 | {
96 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
97 | {
98 | self.detailViewController.date = [self dateForIndexPath:indexPath];
99 | self.detailViewController.dateFormatter = self.detailFormatter;
100 | [self.detailViewController configureView];
101 | }
102 | }
103 |
104 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
105 | {
106 | if ([[segue identifier] isEqualToString:@"showDetail"])
107 | {
108 | NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
109 | [[segue destinationViewController] setDate:[self dateForIndexPath:indexPath]];
110 | [[segue destinationViewController] setDateFormatter:self.detailFormatter];
111 | [[segue destinationViewController] configureView];
112 | }
113 | }
114 |
115 |
116 | #pragma mark - Private Methods
117 |
118 | - (NSDate*)dateForIndexPath:(NSIndexPath*)indexPath
119 | {
120 | self.components.month = indexPath.section;
121 | self.components.day = indexPath.row;
122 | return [[NSCalendar currentCalendar] dateByAddingComponents:self.components toDate:self.beginningOfThisMonth options:0];
123 | }
124 |
125 | - (NSUInteger)numberOfDaysInSection:(NSUInteger)section
126 | {
127 | NSDate *date = [self dateForIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]];
128 | NSRange range = [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit inUnit:NSMonthCalendarUnit forDate:date];
129 | return range.length;
130 | }
131 |
132 | #pragma mark - Getters / Setters
133 |
134 | - (NSIndexSet*)days
135 | {
136 | if (_days == nil)
137 | {
138 | NSMutableIndexSet *days = [NSMutableIndexSet indexSet];
139 |
140 | // 30 years of days
141 | NSUInteger indexCounter = 0;
142 | for (NSUInteger i = 0; i < kNumberOfMonths; i++)
143 | {
144 | NSUInteger daysInMonth = [self numberOfDaysInSection:i];
145 | [days addIndexesInRange:NSMakeRange(indexCounter, daysInMonth)];
146 | indexCounter += daysInMonth;
147 | }
148 |
149 | _days = [days copy];
150 | }
151 |
152 | return _days;
153 | }
154 |
155 |
156 | @end
157 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table/en.lproj/MainStoryboard_iPhone.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table/en.lproj/MainStoryboard_iPad.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
--------------------------------------------------------------------------------
/IndexSet-Backed-Table.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 1437345B178BA05700F0910D /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1437345A178BA05700F0910D /* UIKit.framework */; };
11 | 1437345D178BA05700F0910D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1437345C178BA05700F0910D /* Foundation.framework */; };
12 | 1437345F178BA05700F0910D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1437345E178BA05700F0910D /* CoreGraphics.framework */; };
13 | 14373465178BA05700F0910D /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 14373463178BA05700F0910D /* InfoPlist.strings */; };
14 | 14373467178BA05700F0910D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 14373466178BA05700F0910D /* main.m */; };
15 | 1437346B178BA05700F0910D /* SDAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1437346A178BA05700F0910D /* SDAppDelegate.m */; };
16 | 1437346D178BA05700F0910D /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 1437346C178BA05700F0910D /* Default.png */; };
17 | 1437346F178BA05700F0910D /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 1437346E178BA05700F0910D /* Default@2x.png */; };
18 | 14373471178BA05700F0910D /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 14373470178BA05700F0910D /* Default-568h@2x.png */; };
19 | 14373474178BA05700F0910D /* MainStoryboard_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 14373472178BA05700F0910D /* MainStoryboard_iPhone.storyboard */; };
20 | 14373477178BA05700F0910D /* MainStoryboard_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 14373475178BA05700F0910D /* MainStoryboard_iPad.storyboard */; };
21 | 1437347A178BA05700F0910D /* SDCalendarTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 14373479178BA05700F0910D /* SDCalendarTableViewController.m */; };
22 | 1437347D178BA05700F0910D /* SDDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1437347C178BA05700F0910D /* SDDetailViewController.m */; };
23 | /* End PBXBuildFile section */
24 |
25 | /* Begin PBXFileReference section */
26 | 14373457178BA05700F0910D /* IndexSet-Backed-Table.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "IndexSet-Backed-Table.app"; sourceTree = BUILT_PRODUCTS_DIR; };
27 | 1437345A178BA05700F0910D /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
28 | 1437345C178BA05700F0910D /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
29 | 1437345E178BA05700F0910D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
30 | 14373462178BA05700F0910D /* IndexSet-Backed-Table-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "IndexSet-Backed-Table-Info.plist"; sourceTree = ""; };
31 | 14373464178BA05700F0910D /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
32 | 14373466178BA05700F0910D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
33 | 14373468178BA05700F0910D /* IndexSet-Backed-Table-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "IndexSet-Backed-Table-Prefix.pch"; sourceTree = ""; };
34 | 14373469178BA05700F0910D /* SDAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDAppDelegate.h; sourceTree = ""; };
35 | 1437346A178BA05700F0910D /* SDAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDAppDelegate.m; sourceTree = ""; };
36 | 1437346C178BA05700F0910D /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; };
37 | 1437346E178BA05700F0910D /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; };
38 | 14373470178BA05700F0910D /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; };
39 | 14373473178BA05700F0910D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard_iPhone.storyboard; sourceTree = ""; };
40 | 14373476178BA05700F0910D /* en */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = en; path = en.lproj/MainStoryboard_iPad.storyboard; sourceTree = ""; };
41 | 14373478178BA05700F0910D /* SDCalendarTableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDCalendarTableViewController.h; sourceTree = ""; };
42 | 14373479178BA05700F0910D /* SDCalendarTableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDCalendarTableViewController.m; sourceTree = ""; };
43 | 1437347B178BA05700F0910D /* SDDetailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SDDetailViewController.h; sourceTree = ""; };
44 | 1437347C178BA05700F0910D /* SDDetailViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SDDetailViewController.m; sourceTree = ""; };
45 | /* End PBXFileReference section */
46 |
47 | /* Begin PBXFrameworksBuildPhase section */
48 | 14373454178BA05700F0910D /* Frameworks */ = {
49 | isa = PBXFrameworksBuildPhase;
50 | buildActionMask = 2147483647;
51 | files = (
52 | 1437345B178BA05700F0910D /* UIKit.framework in Frameworks */,
53 | 1437345D178BA05700F0910D /* Foundation.framework in Frameworks */,
54 | 1437345F178BA05700F0910D /* CoreGraphics.framework in Frameworks */,
55 | );
56 | runOnlyForDeploymentPostprocessing = 0;
57 | };
58 | /* End PBXFrameworksBuildPhase section */
59 |
60 | /* Begin PBXGroup section */
61 | 1437344E178BA05700F0910D = {
62 | isa = PBXGroup;
63 | children = (
64 | 14373460178BA05700F0910D /* IndexSet-Backed-Table */,
65 | 14373459178BA05700F0910D /* Frameworks */,
66 | 14373458178BA05700F0910D /* Products */,
67 | );
68 | sourceTree = "";
69 | };
70 | 14373458178BA05700F0910D /* Products */ = {
71 | isa = PBXGroup;
72 | children = (
73 | 14373457178BA05700F0910D /* IndexSet-Backed-Table.app */,
74 | );
75 | name = Products;
76 | sourceTree = "";
77 | };
78 | 14373459178BA05700F0910D /* Frameworks */ = {
79 | isa = PBXGroup;
80 | children = (
81 | 1437345A178BA05700F0910D /* UIKit.framework */,
82 | 1437345C178BA05700F0910D /* Foundation.framework */,
83 | 1437345E178BA05700F0910D /* CoreGraphics.framework */,
84 | );
85 | name = Frameworks;
86 | sourceTree = "";
87 | };
88 | 14373460178BA05700F0910D /* IndexSet-Backed-Table */ = {
89 | isa = PBXGroup;
90 | children = (
91 | 14373469178BA05700F0910D /* SDAppDelegate.h */,
92 | 1437346A178BA05700F0910D /* SDAppDelegate.m */,
93 | 14373472178BA05700F0910D /* MainStoryboard_iPhone.storyboard */,
94 | 14373475178BA05700F0910D /* MainStoryboard_iPad.storyboard */,
95 | 14373478178BA05700F0910D /* SDCalendarTableViewController.h */,
96 | 14373479178BA05700F0910D /* SDCalendarTableViewController.m */,
97 | 1437347B178BA05700F0910D /* SDDetailViewController.h */,
98 | 1437347C178BA05700F0910D /* SDDetailViewController.m */,
99 | 14373461178BA05700F0910D /* Supporting Files */,
100 | );
101 | path = "IndexSet-Backed-Table";
102 | sourceTree = "";
103 | };
104 | 14373461178BA05700F0910D /* Supporting Files */ = {
105 | isa = PBXGroup;
106 | children = (
107 | 14373462178BA05700F0910D /* IndexSet-Backed-Table-Info.plist */,
108 | 14373463178BA05700F0910D /* InfoPlist.strings */,
109 | 14373466178BA05700F0910D /* main.m */,
110 | 14373468178BA05700F0910D /* IndexSet-Backed-Table-Prefix.pch */,
111 | 1437346C178BA05700F0910D /* Default.png */,
112 | 1437346E178BA05700F0910D /* Default@2x.png */,
113 | 14373470178BA05700F0910D /* Default-568h@2x.png */,
114 | );
115 | name = "Supporting Files";
116 | sourceTree = "";
117 | };
118 | /* End PBXGroup section */
119 |
120 | /* Begin PBXNativeTarget section */
121 | 14373456178BA05700F0910D /* IndexSet-Backed-Table */ = {
122 | isa = PBXNativeTarget;
123 | buildConfigurationList = 14373480178BA05700F0910D /* Build configuration list for PBXNativeTarget "IndexSet-Backed-Table" */;
124 | buildPhases = (
125 | 14373453178BA05700F0910D /* Sources */,
126 | 14373454178BA05700F0910D /* Frameworks */,
127 | 14373455178BA05700F0910D /* Resources */,
128 | );
129 | buildRules = (
130 | );
131 | dependencies = (
132 | );
133 | name = "IndexSet-Backed-Table";
134 | productName = "IndexSet-Backed-Table";
135 | productReference = 14373457178BA05700F0910D /* IndexSet-Backed-Table.app */;
136 | productType = "com.apple.product-type.application";
137 | };
138 | /* End PBXNativeTarget section */
139 |
140 | /* Begin PBXProject section */
141 | 1437344F178BA05700F0910D /* Project object */ = {
142 | isa = PBXProject;
143 | attributes = {
144 | CLASSPREFIX = SD;
145 | LastUpgradeCheck = 0460;
146 | ORGANIZATIONNAME = "Sean Dougherty";
147 | };
148 | buildConfigurationList = 14373452178BA05700F0910D /* Build configuration list for PBXProject "IndexSet-Backed-Table" */;
149 | compatibilityVersion = "Xcode 3.2";
150 | developmentRegion = English;
151 | hasScannedForEncodings = 0;
152 | knownRegions = (
153 | en,
154 | );
155 | mainGroup = 1437344E178BA05700F0910D;
156 | productRefGroup = 14373458178BA05700F0910D /* Products */;
157 | projectDirPath = "";
158 | projectRoot = "";
159 | targets = (
160 | 14373456178BA05700F0910D /* IndexSet-Backed-Table */,
161 | );
162 | };
163 | /* End PBXProject section */
164 |
165 | /* Begin PBXResourcesBuildPhase section */
166 | 14373455178BA05700F0910D /* Resources */ = {
167 | isa = PBXResourcesBuildPhase;
168 | buildActionMask = 2147483647;
169 | files = (
170 | 14373465178BA05700F0910D /* InfoPlist.strings in Resources */,
171 | 1437346D178BA05700F0910D /* Default.png in Resources */,
172 | 1437346F178BA05700F0910D /* Default@2x.png in Resources */,
173 | 14373471178BA05700F0910D /* Default-568h@2x.png in Resources */,
174 | 14373474178BA05700F0910D /* MainStoryboard_iPhone.storyboard in Resources */,
175 | 14373477178BA05700F0910D /* MainStoryboard_iPad.storyboard in Resources */,
176 | );
177 | runOnlyForDeploymentPostprocessing = 0;
178 | };
179 | /* End PBXResourcesBuildPhase section */
180 |
181 | /* Begin PBXSourcesBuildPhase section */
182 | 14373453178BA05700F0910D /* Sources */ = {
183 | isa = PBXSourcesBuildPhase;
184 | buildActionMask = 2147483647;
185 | files = (
186 | 14373467178BA05700F0910D /* main.m in Sources */,
187 | 1437346B178BA05700F0910D /* SDAppDelegate.m in Sources */,
188 | 1437347A178BA05700F0910D /* SDCalendarTableViewController.m in Sources */,
189 | 1437347D178BA05700F0910D /* SDDetailViewController.m in Sources */,
190 | );
191 | runOnlyForDeploymentPostprocessing = 0;
192 | };
193 | /* End PBXSourcesBuildPhase section */
194 |
195 | /* Begin PBXVariantGroup section */
196 | 14373463178BA05700F0910D /* InfoPlist.strings */ = {
197 | isa = PBXVariantGroup;
198 | children = (
199 | 14373464178BA05700F0910D /* en */,
200 | );
201 | name = InfoPlist.strings;
202 | sourceTree = "";
203 | };
204 | 14373472178BA05700F0910D /* MainStoryboard_iPhone.storyboard */ = {
205 | isa = PBXVariantGroup;
206 | children = (
207 | 14373473178BA05700F0910D /* en */,
208 | );
209 | name = MainStoryboard_iPhone.storyboard;
210 | sourceTree = "";
211 | };
212 | 14373475178BA05700F0910D /* MainStoryboard_iPad.storyboard */ = {
213 | isa = PBXVariantGroup;
214 | children = (
215 | 14373476178BA05700F0910D /* en */,
216 | );
217 | name = MainStoryboard_iPad.storyboard;
218 | sourceTree = "";
219 | };
220 | /* End PBXVariantGroup section */
221 |
222 | /* Begin XCBuildConfiguration section */
223 | 1437347E178BA05700F0910D /* Debug */ = {
224 | isa = XCBuildConfiguration;
225 | buildSettings = {
226 | ALWAYS_SEARCH_USER_PATHS = NO;
227 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
228 | CLANG_CXX_LIBRARY = "libc++";
229 | CLANG_ENABLE_OBJC_ARC = YES;
230 | CLANG_WARN_CONSTANT_CONVERSION = YES;
231 | CLANG_WARN_EMPTY_BODY = YES;
232 | CLANG_WARN_ENUM_CONVERSION = YES;
233 | CLANG_WARN_INT_CONVERSION = YES;
234 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
235 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
236 | COPY_PHASE_STRIP = NO;
237 | GCC_C_LANGUAGE_STANDARD = gnu99;
238 | GCC_DYNAMIC_NO_PIC = NO;
239 | GCC_OPTIMIZATION_LEVEL = 0;
240 | GCC_PREPROCESSOR_DEFINITIONS = (
241 | "DEBUG=1",
242 | "$(inherited)",
243 | );
244 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
245 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
246 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
247 | GCC_WARN_UNUSED_VARIABLE = YES;
248 | IPHONEOS_DEPLOYMENT_TARGET = 6.1;
249 | ONLY_ACTIVE_ARCH = YES;
250 | SDKROOT = iphoneos;
251 | TARGETED_DEVICE_FAMILY = "1,2";
252 | };
253 | name = Debug;
254 | };
255 | 1437347F178BA05700F0910D /* Release */ = {
256 | isa = XCBuildConfiguration;
257 | buildSettings = {
258 | ALWAYS_SEARCH_USER_PATHS = NO;
259 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
260 | CLANG_CXX_LIBRARY = "libc++";
261 | CLANG_ENABLE_OBJC_ARC = YES;
262 | CLANG_WARN_CONSTANT_CONVERSION = YES;
263 | CLANG_WARN_EMPTY_BODY = YES;
264 | CLANG_WARN_ENUM_CONVERSION = YES;
265 | CLANG_WARN_INT_CONVERSION = YES;
266 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
267 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
268 | COPY_PHASE_STRIP = YES;
269 | GCC_C_LANGUAGE_STANDARD = gnu99;
270 | GCC_WARN_ABOUT_RETURN_TYPE = YES;
271 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
272 | GCC_WARN_UNUSED_VARIABLE = YES;
273 | IPHONEOS_DEPLOYMENT_TARGET = 6.1;
274 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
275 | SDKROOT = iphoneos;
276 | TARGETED_DEVICE_FAMILY = "1,2";
277 | VALIDATE_PRODUCT = YES;
278 | };
279 | name = Release;
280 | };
281 | 14373481178BA05700F0910D /* Debug */ = {
282 | isa = XCBuildConfiguration;
283 | buildSettings = {
284 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
285 | GCC_PREFIX_HEADER = "IndexSet-Backed-Table/IndexSet-Backed-Table-Prefix.pch";
286 | INFOPLIST_FILE = "IndexSet-Backed-Table/IndexSet-Backed-Table-Info.plist";
287 | PRODUCT_NAME = "$(TARGET_NAME)";
288 | WRAPPER_EXTENSION = app;
289 | };
290 | name = Debug;
291 | };
292 | 14373482178BA05700F0910D /* Release */ = {
293 | isa = XCBuildConfiguration;
294 | buildSettings = {
295 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
296 | GCC_PREFIX_HEADER = "IndexSet-Backed-Table/IndexSet-Backed-Table-Prefix.pch";
297 | INFOPLIST_FILE = "IndexSet-Backed-Table/IndexSet-Backed-Table-Info.plist";
298 | PRODUCT_NAME = "$(TARGET_NAME)";
299 | WRAPPER_EXTENSION = app;
300 | };
301 | name = Release;
302 | };
303 | /* End XCBuildConfiguration section */
304 |
305 | /* Begin XCConfigurationList section */
306 | 14373452178BA05700F0910D /* Build configuration list for PBXProject "IndexSet-Backed-Table" */ = {
307 | isa = XCConfigurationList;
308 | buildConfigurations = (
309 | 1437347E178BA05700F0910D /* Debug */,
310 | 1437347F178BA05700F0910D /* Release */,
311 | );
312 | defaultConfigurationIsVisible = 0;
313 | defaultConfigurationName = Release;
314 | };
315 | 14373480178BA05700F0910D /* Build configuration list for PBXNativeTarget "IndexSet-Backed-Table" */ = {
316 | isa = XCConfigurationList;
317 | buildConfigurations = (
318 | 14373481178BA05700F0910D /* Debug */,
319 | 14373482178BA05700F0910D /* Release */,
320 | );
321 | defaultConfigurationIsVisible = 0;
322 | };
323 | /* End XCConfigurationList section */
324 | };
325 | rootObject = 1437344F178BA05700F0910D /* Project object */;
326 | }
327 |
--------------------------------------------------------------------------------