├── .gitignore ├── DTGridView Project ├── Classes │ ├── DTGridViewAppDelegate.h │ ├── DTGridViewAppDelegate.m │ ├── DTGridViewExampleDataSourceAndDelegate.h │ ├── DTGridViewExampleDataSourceAndDelegate.m │ ├── DTInfiniteGridViewExampleViewController.h │ ├── DTInfiniteGridViewExampleViewController.m │ ├── DTSnapGridViewExampleCellView.xib │ ├── DTSnapGridViewExampleView.xib │ ├── DTSnapGridViewExampleViewController.h │ └── DTSnapGridViewExampleViewController.m ├── DTGridView-Info.plist ├── DTGridView.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── DTGridView_Prefix.pch ├── Icon.png ├── License Agreement │ ├── DTLicenseAgreementView.xib │ ├── DTLicenseAgreementViewController.h │ ├── DTLicenseAgreementViewController.m │ └── license.html ├── MainWindow.xib └── main.m ├── DTGridView.h ├── DTGridView.m ├── DTGridViewCell.h ├── DTGridViewCell.m ├── DTGridViewCellInfoProtocol.h ├── DTGridViewController.h ├── DTGridViewController.m ├── DTInfiniteGridView ├── DTInfiniteGridView.h └── DTInfiniteGridView.m ├── DTSnapGridView ├── DTLabelsSnapGridViewCell.h ├── DTLabelsSnapGridViewCell.m ├── DTSnapGridView.h ├── DTSnapGridView.m ├── DTSnapGridViewCell.h └── DTSnapGridViewCell.m └── Readme.textile /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.pbxuser 3 | *perspectivev3 4 | *.mode1v3 5 | *.mode2v3 6 | 7 | *.xcuserstate 8 | *.xcbkptlist -------------------------------------------------------------------------------- /DTGridView Project/Classes/DTGridViewAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // DTGridViewAppDelegate.h 3 | // DTGridView 4 | // 5 | // Created by Daniel Tull on 10.02.2010. 6 | // Copyright Daniel Tull 2010. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DTGridViewAppDelegate : NSObject { 12 | UIWindow *window; 13 | UINavigationController *navigationController; 14 | } 15 | 16 | @property (nonatomic, retain) IBOutlet UIWindow *window; 17 | 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /DTGridView Project/Classes/DTGridViewAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // DTGridViewAppDelegate.m 3 | // DTGridView 4 | // 5 | // Created by Daniel Tull on 10.02.2010. 6 | // Copyright Daniel Tull 2010. All rights reserved. 7 | // 8 | 9 | #import "DTGridViewAppDelegate.h" 10 | #import "DTGridViewExampleDataSourceAndDelegate.h" 11 | #import "DTInfiniteGridViewExampleViewController.h" 12 | #import "DTSnapGridViewExampleViewController.h" 13 | #import "DTLicenseAgreementViewController.h" 14 | @implementation DTGridViewAppDelegate 15 | 16 | @synthesize window; 17 | 18 | 19 | - (void)applicationDidFinishLaunching:(UIApplication *)application { 20 | 21 | UITableViewController *vc = [[UITableViewController alloc] initWithStyle:UITableViewStyleGrouped]; 22 | 23 | navigationController = [[UINavigationController alloc] initWithRootViewController:vc]; 24 | 25 | vc.title = @"DTGridView"; 26 | vc.tableView.delegate = self; 27 | vc.tableView.dataSource = self; 28 | [vc release]; 29 | 30 | [window addSubview:navigationController.view]; 31 | 32 | // Override point for customization after application launch 33 | [window makeKeyAndVisible]; 34 | } 35 | 36 | 37 | - (void)dealloc { 38 | [navigationController release]; 39 | [window release]; 40 | [super dealloc]; 41 | } 42 | 43 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 44 | return 3; 45 | } 46 | 47 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 48 | 49 | if (section == 0) return 1; 50 | if (section == 1) return 3; 51 | 52 | return 0; 53 | } 54 | 55 | - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section { 56 | if (section == 0) return @"Please attribute me when using my source code by linking to my website. Thank you."; 57 | if (section == 2) return @"©2008-2010 Daniel Tull\nwww.danieltull.co.uk"; 58 | 59 | return nil; 60 | } 61 | 62 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 63 | 64 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"]; 65 | 66 | if (!cell) 67 | cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"] autorelease]; 68 | 69 | cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; 70 | 71 | NSString *cellText = nil; 72 | 73 | if (indexPath.section == 0 && indexPath.row == 0) 74 | cellText = @"Source License"; 75 | else if (indexPath.section == 1 && indexPath.row == 0) 76 | cellText = @"DTGridView"; 77 | else if (indexPath.section == 1 && indexPath.row == 1) 78 | cellText = @"DTInfiniteGridView"; 79 | else if (indexPath.section == 1 && indexPath.row == 2) 80 | cellText = @"DTSnapGridView"; 81 | 82 | cell.textLabel.text = cellText; 83 | 84 | return cell; 85 | } 86 | 87 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 88 | 89 | if (indexPath.section == 0 && indexPath.row == 0) { 90 | DTLicenseAgreementViewController *vc = [[DTLicenseAgreementViewController alloc] init]; 91 | [navigationController pushViewController:vc animated:YES]; 92 | [vc release]; 93 | } else if (indexPath.section == 1 && indexPath.row == 0) { 94 | DTGridViewExampleDataSourceAndDelegate *vc = [[DTGridViewExampleDataSourceAndDelegate alloc] init]; 95 | [navigationController pushViewController:vc animated:YES]; 96 | [vc release]; 97 | } else if (indexPath.section == 1 && indexPath.row == 1) { 98 | DTInfiniteGridViewExampleViewController *vc = [[DTInfiniteGridViewExampleViewController alloc] init]; 99 | [navigationController pushViewController:vc animated:YES]; 100 | [vc release]; 101 | } else if (indexPath.section == 1 && indexPath.row == 2) { 102 | DTSnapGridViewExampleViewController *vc = [[DTSnapGridViewExampleViewController alloc] init]; 103 | [navigationController pushViewController:vc animated:YES]; 104 | [vc release]; 105 | } 106 | } 107 | 108 | @end 109 | -------------------------------------------------------------------------------- /DTGridView Project/Classes/DTGridViewExampleDataSourceAndDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // DTGridViewExampleDataSourceAndDelegate.h 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 19.04.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DTGridViewController.h" 11 | 12 | @interface DTGridViewExampleDataSourceAndDelegate : DTGridViewController { 13 | NSArray *colours; 14 | UIPickerView *pickerView; 15 | UINavigationBar *navBar; 16 | } 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /DTGridView Project/Classes/DTGridViewExampleDataSourceAndDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // DTGridViewExampleDataSourceAndDelegate.m 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 19.04.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import "DTGridViewExampleDataSourceAndDelegate.h" 10 | 11 | @implementation DTGridViewExampleDataSourceAndDelegate 12 | 13 | - (id)init { 14 | if (![super init]) 15 | return nil; 16 | 17 | colours = [[NSArray alloc] initWithObjects: 18 | [UIColor redColor], 19 | [UIColor blueColor], 20 | [UIColor greenColor], 21 | [UIColor magentaColor], 22 | [UIColor yellowColor], 23 | [UIColor whiteColor], 24 | [UIColor grayColor], 25 | [UIColor lightGrayColor], 26 | [UIColor purpleColor], 27 | [UIColor orangeColor], 28 | nil]; 29 | 30 | return self; 31 | } 32 | 33 | - (void)dealloc { 34 | [pickerView release]; 35 | [navBar release]; 36 | [colours release]; 37 | [super dealloc]; 38 | } 39 | 40 | - (void)viewDidLoad { 41 | [super viewDidLoad]; 42 | self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Scroll" style:UIBarButtonItemStyleBordered target:self action:@selector(scroll)] autorelease]; 43 | self.title = @"DTGridView"; 44 | self.gridView.delegate = self; 45 | self.gridView.dataSource = self; 46 | self.gridView.bounces = YES; 47 | } 48 | 49 | - (void)scroll { 50 | 51 | if (!pickerView) 52 | pickerView = [[UIPickerView alloc] init]; 53 | 54 | if (!navBar) 55 | navBar = [[UINavigationBar alloc] initWithFrame:self.navigationController.navigationBar.frame]; 56 | 57 | // navBar.title = @"Scroll GridView"; 58 | 59 | navBar.barStyle = UIBarStyleBlack; 60 | UINavigationItem *item = [[UINavigationItem alloc] initWithTitle:@"Scroll GridView"]; 61 | item.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Scroll To" style:UIBarButtonItemStylePlain target:self action:@selector(scrollTo)] autorelease]; 62 | item.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithTitle:@"Done" style:UIBarButtonItemStyleDone target:self action:@selector(endScrolling)] autorelease]; 63 | [navBar pushNavigationItem:item animated:NO]; 64 | [item release]; 65 | [self.navigationController.navigationBar.superview insertSubview:navBar belowSubview:self.navigationController.navigationBar]; 66 | 67 | pickerView.dataSource = self; 68 | pickerView.delegate = self; 69 | [self.view addSubview:pickerView]; 70 | pickerView.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y - pickerView.frame.size.height, pickerView.frame.size.width, pickerView.frame.size.height); 71 | 72 | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleBlackOpaque animated:NO]; 73 | 74 | [UIView beginAnimations:@"pickerShow" context:nil]; 75 | self.gridView.contentInset = UIEdgeInsetsMake(pickerView.frame.size.height, 0, 0, 0);//(self.gridView.frame.origin.x, self.gridView.frame.origin.y + pickerView.frame.size.height, self.gridView.frame.size.width, self.gridView.frame.size.height - pickerView.frame.size.height); 76 | self.gridView.scrollIndicatorInsets = UIEdgeInsetsMake(pickerView.frame.size.height, 0, 0, 0); 77 | 78 | //self.gridView.frame = CGRectMake(self.gridView.frame.origin.x, self.gridView.frame.origin.y + pickerView.frame.size.height, self.gridView.frame.size.width, self.gridView.frame.size.height - pickerView.frame.size.height); 79 | self.navigationController.navigationBar.frame = CGRectMake(self.navigationController.navigationBar.frame.origin.x, self.navigationController.navigationBar.frame.origin.y - self.navigationController.navigationBar.frame.size.height, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height); 80 | pickerView.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y, pickerView.frame.size.width, pickerView.frame.size.height); 81 | 82 | [UIView commitAnimations]; 83 | 84 | //[self.gridView scrollViewToRow:1 column:1 scrollPosition:DTGridViewScrollPositionNone animated:YES]; 85 | } 86 | 87 | - (void)scrollTo { 88 | [self.gridView scrollViewToRow:[pickerView selectedRowInComponent:0] column:[pickerView selectedRowInComponent:1] scrollPosition:DTGridViewScrollPositionNone animated:YES]; 89 | } 90 | 91 | 92 | - (void)endScrolling { 93 | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:NO]; 94 | [UIView beginAnimations:@"pickerHide" context:nil]; 95 | self.gridView.contentInset = UIEdgeInsetsZero; 96 | self.gridView.scrollIndicatorInsets = UIEdgeInsetsZero; 97 | 98 | self.navigationController.navigationBar.frame = CGRectMake(self.navigationController.navigationBar.frame.origin.x, self.navigationController.navigationBar.frame.origin.y + self.navigationController.navigationBar.frame.size.height, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height); 99 | pickerView.frame = CGRectMake(self.view.frame.origin.x, self.view.frame.origin.y - pickerView.frame.size.height, pickerView.frame.size.width, pickerView.frame.size.height); 100 | //self.gridView.frame = CGRectMake(self.gridView.frame.origin.x, self.gridView.frame.origin.y - pickerView.frame.size.height, self.gridView.frame.size.width, self.gridView.frame.size.height + pickerView.frame.size.height); 101 | [UIView commitAnimations]; 102 | } 103 | 104 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 105 | // Return YES for supported orientations 106 | return YES; 107 | } 108 | 109 | #pragma mark - 110 | #pragma mark UIPickerViewDelegate methods 111 | 112 | - (CGFloat)pickerView:(UIPickerView *)pickerView widthForComponent:(NSInteger)component { 113 | return 100.0; 114 | } 115 | 116 | - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { 117 | return 2; 118 | } 119 | 120 | - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { 121 | return 25; 122 | } 123 | 124 | - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { 125 | return [NSString stringWithFormat:@"%i", row]; 126 | } 127 | 128 | #pragma mark - 129 | #pragma mark DTGridViewDataSource methods 130 | 131 | - (NSInteger)numberOfRowsInGridView:(DTGridView *)gridView { 132 | return 25; 133 | } 134 | - (NSInteger)numberOfColumnsInGridView:(DTGridView *)gridView forRowWithIndex:(NSInteger)index { 135 | return 25; 136 | } 137 | 138 | - (CGFloat)gridView:(DTGridView *)gridView heightForRow:(NSInteger)rowIndex { 139 | return 100.0; 140 | } 141 | - (CGFloat)gridView:(DTGridView *)gridView widthForCellAtRow:(NSInteger)rowIndex column:(NSInteger)columnIndex { 142 | return 100.0; 143 | } 144 | 145 | - (DTGridViewCell *)gridView:(DTGridView *)gv viewForRow:(NSInteger)rowIndex column:(NSInteger)columnIndex { 146 | 147 | DTGridViewCell *cell = [gv dequeueReusableCellWithIdentifier:@"cell"]; 148 | 149 | if (!cell) { 150 | cell = [[[DTGridViewCell alloc] initWithReuseIdentifier:@"cell"] autorelease]; 151 | } 152 | 153 | cell.backgroundColor = [colours objectAtIndex:(random() % 10)]; 154 | 155 | return cell; 156 | } 157 | 158 | #pragma mark - 159 | #pragma mark DTGridViewDelegate methods 160 | 161 | - (void)gridView:(DTGridView *)gv selectionMadeAtRow:(NSInteger)rowIndex column:(NSInteger)columnIndex { 162 | NSLog(@"%@:%@ %@", self, NSStringFromSelector(_cmd), [gv cellForRow:rowIndex column:columnIndex]); 163 | 164 | } 165 | 166 | - (void)gridView:(DTGridView *)gridView scrolledToEdge:(DTGridViewEdge)edge { 167 | } 168 | 169 | @end 170 | -------------------------------------------------------------------------------- /DTGridView Project/Classes/DTInfiniteGridViewExampleViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DTInfiniteGridViewExampleViewController.h 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 11.08.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DTInfiniteGridView.h" 11 | 12 | @interface DTInfiniteGridViewExampleViewController : UIViewController { 13 | DTInfiniteGridView *gridView; 14 | } 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /DTGridView Project/Classes/DTInfiniteGridViewExampleViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DTInfiniteGridViewExampleViewController.m 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 11.08.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import "DTInfiniteGridViewExampleViewController.h" 10 | 11 | 12 | @implementation DTInfiniteGridViewExampleViewController 13 | 14 | - (void)viewDidLoad { 15 | [super viewDidLoad]; 16 | self.title = @"DTInfinteGridView"; 17 | self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 18 | self.view.autoresizesSubviews = YES; 19 | gridView = [[DTInfiniteGridView alloc] initWithFrame:self.view.bounds]; 20 | gridView.autoresizingMask = self.view.autoresizingMask; 21 | gridView.dataSource = self; 22 | gridView.infiniteVerticalScrolling = NO; 23 | gridView.infiniteHorizontalScrolling = YES; 24 | gridView.delegate = self; 25 | gridView.pagingEnabled = NO; 26 | [self.view addSubview:gridView]; 27 | } 28 | 29 | 30 | /* 31 | // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 32 | - (void)viewDidLoad { 33 | [super viewDidLoad]; 34 | } 35 | */ 36 | 37 | /* 38 | // Override to allow orientations other than the default portrait orientation. 39 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 40 | // Return YES for supported orientations 41 | return (interfaceOrientation == UIInterfaceOrientationPortrait); 42 | } 43 | */ 44 | 45 | - (void)didReceiveMemoryWarning { 46 | // Releases the view if it doesn't have a superview. 47 | [super didReceiveMemoryWarning]; 48 | 49 | // Release any cached data, images, etc that aren't in use. 50 | } 51 | 52 | - (void)viewDidUnload { 53 | // Release any retained subviews of the main view. 54 | // e.g. self.myOutlet = nil; 55 | } 56 | 57 | 58 | - (void)dealloc { 59 | [super dealloc]; 60 | } 61 | - (NSInteger)numberOfRowsInGridView:(DTGridView *)gridView { 62 | return 1; 63 | } 64 | - (NSInteger)numberOfColumnsInGridView:(DTGridView *)gridView forRowWithIndex:(NSInteger)index { 65 | return 4; 66 | } 67 | - (CGFloat)gridView:(DTGridView *)gv heightForRow:(NSInteger)rowIndex { 68 | return gv.frame.size.height; 69 | } 70 | - (CGFloat)gridView:(DTGridView *)gv widthForCellAtRow:(NSInteger)rowIndex column:(NSInteger)columnIndex { 71 | return gv.frame.size.width / 2; 72 | } 73 | - (DTGridViewCell *)gridView:(DTGridView *)gv viewForRow:(NSInteger)rowIndex column:(NSInteger)columnIndex { 74 | DTGridViewCell *view = [[gv dequeueReusableCellWithIdentifier:@"cell"] retain]; 75 | 76 | if (!view) 77 | view = [[DTGridViewCell alloc] initWithReuseIdentifier:@"cell"]; 78 | 79 | if (columnIndex == 0) 80 | view.backgroundColor = [UIColor redColor]; 81 | else if (columnIndex == 1) 82 | view.backgroundColor = [UIColor blueColor]; 83 | else if (columnIndex == 2) 84 | view.backgroundColor = [UIColor orangeColor]; 85 | else if (columnIndex == 3) 86 | view.backgroundColor = [UIColor yellowColor]; 87 | else 88 | NSLog(@"%@:%@ FAIL: %i", self, NSStringFromSelector(_cmd), columnIndex); 89 | 90 | return [view autorelease]; 91 | } 92 | 93 | @end 94 | -------------------------------------------------------------------------------- /DTGridView Project/Classes/DTSnapGridViewExampleCellView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 768 5 | 10A421a 6 | 732 7 | 1038 8 | 435.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 58 12 | 13 | 14 | YES 15 | 16 | 17 | 18 | YES 19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 20 | 21 | 22 | YES 23 | 24 | YES 25 | 26 | 27 | YES 28 | 29 | 30 | 31 | YES 32 | 33 | IBFilesOwner 34 | 35 | 36 | IBFirstResponder 37 | 38 | 39 | 40 | 274 41 | 42 | YES 43 | 44 | 45 | 292 46 | {{0, 20}, {35, 21}} 47 | 48 | NO 49 | YES 50 | NO 51 | Title 52 | 53 | Helvetica-Bold 54 | 17 55 | 16 56 | 57 | 58 | 1 59 | MCAwIDAAA 60 | 61 | 62 | 1 63 | 10 64 | 65 | 66 | 67 | 292 68 | {{0, 49}, {57, 57}} 69 | 70 | NO 71 | NO 72 | 4 73 | NO 74 | 75 | NSImage 76 | Icon.png 77 | 78 | 79 | 80 | {112, 126} 81 | 82 | 83 | 3 84 | MQA 85 | 86 | 87 | 88 | 89 | 90 | YES 91 | 92 | 93 | 94 | YES 95 | 96 | 0 97 | 98 | 99 | 100 | 101 | 102 | 1 103 | 104 | 105 | YES 106 | 107 | 108 | 109 | 110 | 111 | 112 | -1 113 | 114 | 115 | File's Owner 116 | 117 | 118 | -2 119 | 120 | 121 | 122 | 123 | 3 124 | 125 | 126 | 127 | 128 | 4 129 | 130 | 131 | 132 | 133 | 134 | 135 | YES 136 | 137 | YES 138 | -2.CustomClassName 139 | 1.CustomClassName 140 | 1.IBEditorWindowLastContentRect 141 | 1.IBPluginDependency 142 | 3.IBPluginDependency 143 | 4.IBPluginDependency 144 | 145 | 146 | YES 147 | UIResponder 148 | DTSnapGridViewCell 149 | {{354, 730}, {112, 126}} 150 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 151 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 152 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 153 | 154 | 155 | 156 | YES 157 | 158 | 159 | YES 160 | 161 | 162 | 163 | 164 | YES 165 | 166 | 167 | YES 168 | 169 | 170 | 171 | 9 172 | 173 | 174 | 175 | YES 176 | 177 | DTGridViewCell 178 | UIView 179 | 180 | delegate 181 | id 182 | 183 | 184 | IBProjectSource 185 | DTGridView/DTGridViewCell.h 186 | 187 | 188 | 189 | DTSnapGridViewCell 190 | DTGridViewCell 191 | 192 | IBProjectSource 193 | DTSnapGridView/DTSnapGridViewCell.h 194 | 195 | 196 | 197 | UILabel 198 | 199 | IBProjectSource 200 | DTLabels/UILabel+DTCopyLabel.h 201 | 202 | 203 | 204 | 205 | YES 206 | 207 | NSObject 208 | 209 | IBFrameworkSource 210 | Foundation.framework/Headers/NSError.h 211 | 212 | 213 | 214 | NSObject 215 | 216 | IBFrameworkSource 217 | Foundation.framework/Headers/NSFileManager.h 218 | 219 | 220 | 221 | NSObject 222 | 223 | IBFrameworkSource 224 | Foundation.framework/Headers/NSKeyValueCoding.h 225 | 226 | 227 | 228 | NSObject 229 | 230 | IBFrameworkSource 231 | Foundation.framework/Headers/NSKeyValueObserving.h 232 | 233 | 234 | 235 | NSObject 236 | 237 | IBFrameworkSource 238 | Foundation.framework/Headers/NSKeyedArchiver.h 239 | 240 | 241 | 242 | NSObject 243 | 244 | IBFrameworkSource 245 | Foundation.framework/Headers/NSNetServices.h 246 | 247 | 248 | 249 | NSObject 250 | 251 | IBFrameworkSource 252 | Foundation.framework/Headers/NSObject.h 253 | 254 | 255 | 256 | NSObject 257 | 258 | IBFrameworkSource 259 | Foundation.framework/Headers/NSPort.h 260 | 261 | 262 | 263 | NSObject 264 | 265 | IBFrameworkSource 266 | Foundation.framework/Headers/NSRunLoop.h 267 | 268 | 269 | 270 | NSObject 271 | 272 | IBFrameworkSource 273 | Foundation.framework/Headers/NSStream.h 274 | 275 | 276 | 277 | NSObject 278 | 279 | IBFrameworkSource 280 | Foundation.framework/Headers/NSThread.h 281 | 282 | 283 | 284 | NSObject 285 | 286 | IBFrameworkSource 287 | Foundation.framework/Headers/NSURL.h 288 | 289 | 290 | 291 | NSObject 292 | 293 | IBFrameworkSource 294 | Foundation.framework/Headers/NSURLConnection.h 295 | 296 | 297 | 298 | NSObject 299 | 300 | IBFrameworkSource 301 | Foundation.framework/Headers/NSXMLParser.h 302 | 303 | 304 | 305 | NSObject 306 | 307 | IBFrameworkSource 308 | UIKit.framework/Headers/UIAccessibility.h 309 | 310 | 311 | 312 | NSObject 313 | 314 | IBFrameworkSource 315 | UIKit.framework/Headers/UINibLoading.h 316 | 317 | 318 | 319 | NSObject 320 | 321 | IBFrameworkSource 322 | UIKit.framework/Headers/UIResponder.h 323 | 324 | 325 | 326 | UIImageView 327 | UIView 328 | 329 | IBFrameworkSource 330 | UIKit.framework/Headers/UIImageView.h 331 | 332 | 333 | 334 | UILabel 335 | UIView 336 | 337 | IBFrameworkSource 338 | UIKit.framework/Headers/UILabel.h 339 | 340 | 341 | 342 | UIResponder 343 | NSObject 344 | 345 | 346 | 347 | UIView 348 | 349 | IBFrameworkSource 350 | UIKit.framework/Headers/UITextField.h 351 | 352 | 353 | 354 | UIView 355 | UIResponder 356 | 357 | IBFrameworkSource 358 | UIKit.framework/Headers/UIView.h 359 | 360 | 361 | 362 | 363 | 0 364 | 365 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 366 | 367 | 368 | 369 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 370 | 371 | 372 | YES 373 | ../DTKit.xcodeproj 374 | 3 375 | 3.0 376 | 377 | 378 | -------------------------------------------------------------------------------- /DTGridView Project/Classes/DTSnapGridViewExampleView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 544 5 | 10A394 6 | 732 7 | 1027.1 8 | 430.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 58 12 | 13 | 14 | YES 15 | 16 | 17 | 18 | YES 19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 20 | 21 | 22 | YES 23 | 24 | YES 25 | 26 | 27 | YES 28 | 29 | 30 | 31 | YES 32 | 33 | IBFilesOwner 34 | 35 | 36 | IBFirstResponder 37 | 38 | 39 | 40 | 274 41 | 42 | YES 43 | 44 | 45 | 274 46 | {320, 460} 47 | 48 | YES 49 | YES 50 | NO 51 | 52 | 53 | {320, 460} 54 | 55 | 56 | 3 57 | MQA 58 | 59 | 60 | 61 | 62 | 63 | YES 64 | 65 | 66 | view 67 | 68 | 69 | 70 | 4 71 | 72 | 73 | 74 | dataSource 75 | 76 | 77 | 78 | 5 79 | 80 | 81 | 82 | snapGridView 83 | 84 | 85 | 86 | 6 87 | 88 | 89 | 90 | 91 | YES 92 | 93 | 0 94 | 95 | 96 | 97 | 98 | 99 | 1 100 | 101 | 102 | YES 103 | 104 | 105 | 106 | 107 | 108 | -1 109 | 110 | 111 | File's Owner 112 | 113 | 114 | -2 115 | 116 | 117 | 118 | 119 | 3 120 | 121 | 122 | 123 | 124 | 125 | 126 | YES 127 | 128 | YES 129 | -1.CustomClassName 130 | -2.CustomClassName 131 | 1.IBEditorWindowLastContentRect 132 | 1.IBPluginDependency 133 | 3.CustomClassName 134 | 3.IBPluginDependency 135 | 136 | 137 | YES 138 | DTSnapGridViewExampleViewController 139 | UIResponder 140 | {{354, 396}, {320, 460}} 141 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 142 | DTSnapGridView 143 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 144 | 145 | 146 | 147 | YES 148 | 149 | 150 | YES 151 | 152 | 153 | 154 | 155 | YES 156 | 157 | 158 | YES 159 | 160 | 161 | 162 | 6 163 | 164 | 165 | 166 | YES 167 | 168 | DTGridView 169 | UIScrollView 170 | 171 | YES 172 | 173 | YES 174 | dataSource 175 | gridDelegate 176 | 177 | 178 | YES 179 | NSObject 180 | NSObject 181 | 182 | 183 | 184 | IBProjectSource 185 | DTGridView/DTGridView.h 186 | 187 | 188 | 189 | DTSnapGridView 190 | DTGridView 191 | 192 | gridDelegate 193 | NSObject 194 | 195 | 196 | IBProjectSource 197 | DTSnapGridView/DTSnapGridView.h 198 | 199 | 200 | 201 | DTSnapGridViewExampleViewController 202 | UIViewController 203 | 204 | snapGridView 205 | DTSnapGridView 206 | 207 | 208 | IBProjectSource 209 | DTSnapGridView/DTSnapGridViewExampleViewController.h 210 | 211 | 212 | 213 | 214 | 0 215 | 216 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 217 | 218 | 219 | 220 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 221 | 222 | 223 | YES 224 | ../DTKit.xcodeproj 225 | 3 226 | 3.0 227 | 228 | 229 | -------------------------------------------------------------------------------- /DTGridView Project/Classes/DTSnapGridViewExampleViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DTSnapGridViewExampleViewController.h 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 09.07.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DTSnapGridView.h" 11 | 12 | @interface DTSnapGridViewExampleViewController : UIViewController { 13 | DTSnapGridView *snapGridView; 14 | } 15 | 16 | @property (nonatomic, retain) IBOutlet DTSnapGridView *snapGridView; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /DTGridView Project/Classes/DTSnapGridViewExampleViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DTSnapGridViewExampleViewController.m 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 09.07.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import "DTSnapGridViewExampleViewController.h" 10 | 11 | @implementation DTSnapGridViewExampleViewController 12 | 13 | @synthesize snapGridView; 14 | 15 | - (id)init { 16 | 17 | if (!(self = [self initWithNibName:@"DTSnapGridViewExampleView" bundle:nil])) return nil; 18 | 19 | self.title = @"DTSnapGridView"; 20 | 21 | return self; 22 | 23 | } 24 | 25 | 26 | - (void)didReceiveMemoryWarning { 27 | // Releases the view if it doesn't have a superview. 28 | [super didReceiveMemoryWarning]; 29 | 30 | // Release any cached data, images, etc that aren't in use. 31 | } 32 | 33 | - (void)viewDidUnload { 34 | // Release any retained subviews of the main view. 35 | // e.g. self.myOutlet = nil; 36 | } 37 | 38 | 39 | - (void)dealloc { 40 | [super dealloc]; 41 | } 42 | 43 | #pragma mark DTGridViewDataSource Methods 44 | 45 | - (NSInteger)numberOfRowsInGridView:(DTGridView *)gv { 46 | return 1; 47 | } 48 | 49 | - (NSInteger)numberOfColumnsInGridView:(DTGridView *)gv forRowWithIndex:(NSInteger)index { 50 | return 20; 51 | } 52 | 53 | - (CGFloat)gridView:(DTGridView *)gv heightForRow:(NSInteger)rowIndex { 54 | return gv.frame.size.height; 55 | } 56 | 57 | - (CGFloat)gridView:(DTGridView *)gv widthForCellAtRow:(NSInteger)rowIndex column:(NSInteger)columnIndex { 58 | return gv.frame.size.width/3.0; 59 | } 60 | 61 | - (DTGridViewCell *)gridView:(DTGridView *)gv viewForRow:(NSInteger)rowIndex column:(NSInteger)columnIndex { 62 | 63 | NSLog(@"%@:%@", self, NSStringFromSelector(_cmd)); 64 | 65 | DTGridViewCell *cell = [gv dequeueReusableCellWithIdentifier:@"cell"]; 66 | 67 | if (!cell) { 68 | cell = [[[NSBundle mainBundle] loadNibNamed:@"DTSnapGridViewExampleCellView" owner:self options:nil] objectAtIndex:0]; 69 | cell.identifier = @"cell"; 70 | } 71 | 72 | return cell; 73 | } 74 | 75 | 76 | @end 77 | -------------------------------------------------------------------------------- /DTGridView Project/DTGridView-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | English 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleDocumentTypes 10 | 11 | CFBundleExecutable 12 | ${EXECUTABLE_NAME} 13 | CFBundleIconFile 14 | 15 | CFBundleIdentifier 16 | uk.co.danieltull.${PRODUCT_NAME:rfc1034identifier} 17 | CFBundleInfoDictionaryVersion 18 | 6.0 19 | CFBundleName 20 | ${PRODUCT_NAME} 21 | CFBundlePackageType 22 | APPL 23 | CFBundleSignature 24 | ???? 25 | CFBundleURLTypes 26 | 27 | CFBundleVersion 28 | 1.0 29 | LSRequiresIPhoneOS 30 | 31 | NSMainNibFile 32 | MainWindow 33 | UIPrerenderedIcon 34 | 35 | UTExportedTypeDeclarations 36 | 37 | UTImportedTypeDeclarations 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /DTGridView Project/DTGridView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 45; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1D3623260D0F684500981E51 /* DTGridViewAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 1D3623250D0F684500981E51 /* DTGridViewAppDelegate.m */; }; 11 | 1D60589B0D05DD56006BFB54 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 29B97316FDCFA39411CA2CEA /* main.m */; }; 12 | 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1D30AB110D05D00D00671497 /* Foundation.framework */; }; 13 | 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */; }; 14 | 2428E8D0112375660019252F /* DTGridViewExampleDataSourceAndDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2428E8C9112375660019252F /* DTGridViewExampleDataSourceAndDelegate.m */; }; 15 | 2428E8D1112375660019252F /* DTInfiniteGridViewExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2428E8CB112375660019252F /* DTInfiniteGridViewExampleViewController.m */; }; 16 | 2428E8D2112375660019252F /* DTSnapGridViewExampleCellView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2428E8CC112375660019252F /* DTSnapGridViewExampleCellView.xib */; }; 17 | 2428E8D3112375660019252F /* DTSnapGridViewExampleView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2428E8CD112375660019252F /* DTSnapGridViewExampleView.xib */; }; 18 | 2428E8D4112375660019252F /* DTSnapGridViewExampleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2428E8CF112375660019252F /* DTSnapGridViewExampleViewController.m */; }; 19 | 2428E905112377B30019252F /* DTLicenseAgreementView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2428E901112377B30019252F /* DTLicenseAgreementView.xib */; }; 20 | 2428E906112377B30019252F /* DTLicenseAgreementViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2428E903112377B30019252F /* DTLicenseAgreementViewController.m */; }; 21 | 2428E907112377B30019252F /* license.html in Resources */ = {isa = PBXBuildFile; fileRef = 2428E904112377B30019252F /* license.html */; }; 22 | 2428E919112379F10019252F /* Icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 2428E918112379F10019252F /* Icon.png */; }; 23 | 24388F8512B8D4F800848476 /* DTGridView.m in Sources */ = {isa = PBXBuildFile; fileRef = 24388EA212B8D4F800848476 /* DTGridView.m */; }; 24 | 24388F8612B8D4F800848476 /* DTGridViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 24388EA412B8D4F800848476 /* DTGridViewCell.m */; }; 25 | 24388F8712B8D4F800848476 /* DTGridViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 24388EA712B8D4F800848476 /* DTGridViewController.m */; }; 26 | 24388F8812B8D4F800848476 /* DTInfiniteGridView.m in Sources */ = {isa = PBXBuildFile; fileRef = 24388EAA12B8D4F800848476 /* DTInfiniteGridView.m */; }; 27 | 24388F8912B8D4F800848476 /* DTLabelsSnapGridViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 24388EAD12B8D4F800848476 /* DTLabelsSnapGridViewCell.m */; }; 28 | 24388F8A12B8D4F800848476 /* DTSnapGridView.m in Sources */ = {isa = PBXBuildFile; fileRef = 24388EAF12B8D4F800848476 /* DTSnapGridView.m */; }; 29 | 24388F8B12B8D4F800848476 /* DTSnapGridViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 24388EB112B8D4F800848476 /* DTSnapGridViewCell.m */; }; 30 | 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 288765FC0DF74451002DB57D /* CoreGraphics.framework */; }; 31 | 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28AD733E0D9D9553002E5188 /* MainWindow.xib */; }; 32 | /* End PBXBuildFile section */ 33 | 34 | /* Begin PBXFileReference section */ 35 | 1D30AB110D05D00D00671497 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 36 | 1D3623240D0F684500981E51 /* DTGridViewAppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTGridViewAppDelegate.h; sourceTree = ""; }; 37 | 1D3623250D0F684500981E51 /* DTGridViewAppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTGridViewAppDelegate.m; sourceTree = ""; }; 38 | 1D6058910D05DD3D006BFB54 /* DTGridView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DTGridView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 40 | 2428E8C8112375660019252F /* DTGridViewExampleDataSourceAndDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTGridViewExampleDataSourceAndDelegate.h; sourceTree = ""; }; 41 | 2428E8C9112375660019252F /* DTGridViewExampleDataSourceAndDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTGridViewExampleDataSourceAndDelegate.m; sourceTree = ""; }; 42 | 2428E8CA112375660019252F /* DTInfiniteGridViewExampleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTInfiniteGridViewExampleViewController.h; sourceTree = ""; }; 43 | 2428E8CB112375660019252F /* DTInfiniteGridViewExampleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTInfiniteGridViewExampleViewController.m; sourceTree = ""; }; 44 | 2428E8CC112375660019252F /* DTSnapGridViewExampleCellView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DTSnapGridViewExampleCellView.xib; sourceTree = ""; }; 45 | 2428E8CD112375660019252F /* DTSnapGridViewExampleView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DTSnapGridViewExampleView.xib; sourceTree = ""; }; 46 | 2428E8CE112375660019252F /* DTSnapGridViewExampleViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTSnapGridViewExampleViewController.h; sourceTree = ""; }; 47 | 2428E8CF112375660019252F /* DTSnapGridViewExampleViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTSnapGridViewExampleViewController.m; sourceTree = ""; }; 48 | 2428E901112377B30019252F /* DTLicenseAgreementView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = DTLicenseAgreementView.xib; sourceTree = ""; }; 49 | 2428E902112377B30019252F /* DTLicenseAgreementViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTLicenseAgreementViewController.h; sourceTree = ""; }; 50 | 2428E903112377B30019252F /* DTLicenseAgreementViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTLicenseAgreementViewController.m; sourceTree = ""; }; 51 | 2428E904112377B30019252F /* license.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = license.html; sourceTree = ""; }; 52 | 2428E918112379F10019252F /* Icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Icon.png; sourceTree = ""; }; 53 | 24388EA112B8D4F800848476 /* DTGridView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTGridView.h; sourceTree = ""; }; 54 | 24388EA212B8D4F800848476 /* DTGridView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTGridView.m; sourceTree = ""; }; 55 | 24388EA312B8D4F800848476 /* DTGridViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTGridViewCell.h; sourceTree = ""; }; 56 | 24388EA412B8D4F800848476 /* DTGridViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTGridViewCell.m; sourceTree = ""; }; 57 | 24388EA512B8D4F800848476 /* DTGridViewCellInfoProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTGridViewCellInfoProtocol.h; sourceTree = ""; }; 58 | 24388EA612B8D4F800848476 /* DTGridViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTGridViewController.h; sourceTree = ""; }; 59 | 24388EA712B8D4F800848476 /* DTGridViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTGridViewController.m; sourceTree = ""; }; 60 | 24388EA912B8D4F800848476 /* DTInfiniteGridView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTInfiniteGridView.h; sourceTree = ""; }; 61 | 24388EAA12B8D4F800848476 /* DTInfiniteGridView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTInfiniteGridView.m; sourceTree = ""; }; 62 | 24388EAC12B8D4F800848476 /* DTLabelsSnapGridViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTLabelsSnapGridViewCell.h; sourceTree = ""; }; 63 | 24388EAD12B8D4F800848476 /* DTLabelsSnapGridViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTLabelsSnapGridViewCell.m; sourceTree = ""; }; 64 | 24388EAE12B8D4F800848476 /* DTSnapGridView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTSnapGridView.h; sourceTree = ""; }; 65 | 24388EAF12B8D4F800848476 /* DTSnapGridView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTSnapGridView.m; sourceTree = ""; }; 66 | 24388EB012B8D4F800848476 /* DTSnapGridViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTSnapGridViewCell.h; sourceTree = ""; }; 67 | 24388EB112B8D4F800848476 /* DTSnapGridViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTSnapGridViewCell.m; sourceTree = ""; }; 68 | 288765FC0DF74451002DB57D /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 69 | 28AD733E0D9D9553002E5188 /* MainWindow.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainWindow.xib; sourceTree = ""; }; 70 | 29B97316FDCFA39411CA2CEA /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 71 | 32CA4F630368D1EE00C91783 /* DTGridView_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTGridView_Prefix.pch; sourceTree = ""; }; 72 | 8D1107310486CEB800E47090 /* DTGridView-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "DTGridView-Info.plist"; plistStructureDefinitionIdentifier = "com.apple.xcode.plist.structure-definition.iphone.info-plist"; sourceTree = ""; }; 73 | /* End PBXFileReference section */ 74 | 75 | /* Begin PBXFrameworksBuildPhase section */ 76 | 1D60588F0D05DD3D006BFB54 /* Frameworks */ = { 77 | isa = PBXFrameworksBuildPhase; 78 | buildActionMask = 2147483647; 79 | files = ( 80 | 1D60589F0D05DD5A006BFB54 /* Foundation.framework in Frameworks */, 81 | 1DF5F4E00D08C38300B7A737 /* UIKit.framework in Frameworks */, 82 | 288765FD0DF74451002DB57D /* CoreGraphics.framework in Frameworks */, 83 | ); 84 | runOnlyForDeploymentPostprocessing = 0; 85 | }; 86 | /* End PBXFrameworksBuildPhase section */ 87 | 88 | /* Begin PBXGroup section */ 89 | 080E96DDFE201D6D7F000001 /* Classes */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | 1D3623240D0F684500981E51 /* DTGridViewAppDelegate.h */, 93 | 1D3623250D0F684500981E51 /* DTGridViewAppDelegate.m */, 94 | 2428E8C8112375660019252F /* DTGridViewExampleDataSourceAndDelegate.h */, 95 | 2428E8C9112375660019252F /* DTGridViewExampleDataSourceAndDelegate.m */, 96 | 2428E8CA112375660019252F /* DTInfiniteGridViewExampleViewController.h */, 97 | 2428E8CB112375660019252F /* DTInfiniteGridViewExampleViewController.m */, 98 | 2428E8CC112375660019252F /* DTSnapGridViewExampleCellView.xib */, 99 | 2428E8CD112375660019252F /* DTSnapGridViewExampleView.xib */, 100 | 2428E8CE112375660019252F /* DTSnapGridViewExampleViewController.h */, 101 | 2428E8CF112375660019252F /* DTSnapGridViewExampleViewController.m */, 102 | ); 103 | path = Classes; 104 | sourceTree = ""; 105 | }; 106 | 19C28FACFE9D520D11CA2CBB /* Products */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 1D6058910D05DD3D006BFB54 /* DTGridView.app */, 110 | ); 111 | name = Products; 112 | sourceTree = ""; 113 | }; 114 | 2428E900112377B30019252F /* License Agreement */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 2428E901112377B30019252F /* DTLicenseAgreementView.xib */, 118 | 2428E902112377B30019252F /* DTLicenseAgreementViewController.h */, 119 | 2428E903112377B30019252F /* DTLicenseAgreementViewController.m */, 120 | 2428E904112377B30019252F /* license.html */, 121 | ); 122 | path = "License Agreement"; 123 | sourceTree = ""; 124 | }; 125 | 24388D3912B8D4F700848476 /* DTGridView */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | 24388EA112B8D4F800848476 /* DTGridView.h */, 129 | 24388EA212B8D4F800848476 /* DTGridView.m */, 130 | 24388EA312B8D4F800848476 /* DTGridViewCell.h */, 131 | 24388EA412B8D4F800848476 /* DTGridViewCell.m */, 132 | 24388EA512B8D4F800848476 /* DTGridViewCellInfoProtocol.h */, 133 | 24388EA612B8D4F800848476 /* DTGridViewController.h */, 134 | 24388EA712B8D4F800848476 /* DTGridViewController.m */, 135 | 24388EA812B8D4F800848476 /* DTInfiniteGridView */, 136 | 24388EAB12B8D4F800848476 /* DTSnapGridView */, 137 | ); 138 | name = DTGridView; 139 | path = ..; 140 | sourceTree = SOURCE_ROOT; 141 | }; 142 | 24388EA812B8D4F800848476 /* DTInfiniteGridView */ = { 143 | isa = PBXGroup; 144 | children = ( 145 | 24388EA912B8D4F800848476 /* DTInfiniteGridView.h */, 146 | 24388EAA12B8D4F800848476 /* DTInfiniteGridView.m */, 147 | ); 148 | path = DTInfiniteGridView; 149 | sourceTree = ""; 150 | }; 151 | 24388EAB12B8D4F800848476 /* DTSnapGridView */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | 24388EAC12B8D4F800848476 /* DTLabelsSnapGridViewCell.h */, 155 | 24388EAD12B8D4F800848476 /* DTLabelsSnapGridViewCell.m */, 156 | 24388EAE12B8D4F800848476 /* DTSnapGridView.h */, 157 | 24388EAF12B8D4F800848476 /* DTSnapGridView.m */, 158 | 24388EB012B8D4F800848476 /* DTSnapGridViewCell.h */, 159 | 24388EB112B8D4F800848476 /* DTSnapGridViewCell.m */, 160 | ); 161 | path = DTSnapGridView; 162 | sourceTree = ""; 163 | }; 164 | 29B97314FDCFA39411CA2CEA /* CustomTemplate */ = { 165 | isa = PBXGroup; 166 | children = ( 167 | 24388D3912B8D4F700848476 /* DTGridView */, 168 | 2428E900112377B30019252F /* License Agreement */, 169 | 080E96DDFE201D6D7F000001 /* Classes */, 170 | 29B97315FDCFA39411CA2CEA /* Other Sources */, 171 | 29B97317FDCFA39411CA2CEA /* Resources */, 172 | 29B97323FDCFA39411CA2CEA /* Frameworks */, 173 | 19C28FACFE9D520D11CA2CBB /* Products */, 174 | ); 175 | name = CustomTemplate; 176 | sourceTree = ""; 177 | }; 178 | 29B97315FDCFA39411CA2CEA /* Other Sources */ = { 179 | isa = PBXGroup; 180 | children = ( 181 | 32CA4F630368D1EE00C91783 /* DTGridView_Prefix.pch */, 182 | 29B97316FDCFA39411CA2CEA /* main.m */, 183 | ); 184 | name = "Other Sources"; 185 | sourceTree = ""; 186 | }; 187 | 29B97317FDCFA39411CA2CEA /* Resources */ = { 188 | isa = PBXGroup; 189 | children = ( 190 | 2428E918112379F10019252F /* Icon.png */, 191 | 28AD733E0D9D9553002E5188 /* MainWindow.xib */, 192 | 8D1107310486CEB800E47090 /* DTGridView-Info.plist */, 193 | ); 194 | name = Resources; 195 | sourceTree = ""; 196 | }; 197 | 29B97323FDCFA39411CA2CEA /* Frameworks */ = { 198 | isa = PBXGroup; 199 | children = ( 200 | 1DF5F4DF0D08C38300B7A737 /* UIKit.framework */, 201 | 1D30AB110D05D00D00671497 /* Foundation.framework */, 202 | 288765FC0DF74451002DB57D /* CoreGraphics.framework */, 203 | ); 204 | name = Frameworks; 205 | sourceTree = ""; 206 | }; 207 | /* End PBXGroup section */ 208 | 209 | /* Begin PBXNativeTarget section */ 210 | 1D6058900D05DD3D006BFB54 /* DTGridView */ = { 211 | isa = PBXNativeTarget; 212 | buildConfigurationList = 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "DTGridView" */; 213 | buildPhases = ( 214 | 1D60588D0D05DD3D006BFB54 /* Resources */, 215 | 1D60588E0D05DD3D006BFB54 /* Sources */, 216 | 1D60588F0D05DD3D006BFB54 /* Frameworks */, 217 | ); 218 | buildRules = ( 219 | ); 220 | dependencies = ( 221 | ); 222 | name = DTGridView; 223 | productName = DTGridView; 224 | productReference = 1D6058910D05DD3D006BFB54 /* DTGridView.app */; 225 | productType = "com.apple.product-type.application"; 226 | }; 227 | /* End PBXNativeTarget section */ 228 | 229 | /* Begin PBXProject section */ 230 | 29B97313FDCFA39411CA2CEA /* Project object */ = { 231 | isa = PBXProject; 232 | attributes = { 233 | LastUpgradeCheck = 0420; 234 | }; 235 | buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "DTGridView" */; 236 | compatibilityVersion = "Xcode 3.1"; 237 | developmentRegion = English; 238 | hasScannedForEncodings = 1; 239 | knownRegions = ( 240 | en, 241 | ); 242 | mainGroup = 29B97314FDCFA39411CA2CEA /* CustomTemplate */; 243 | projectDirPath = ""; 244 | projectRoot = ""; 245 | targets = ( 246 | 1D6058900D05DD3D006BFB54 /* DTGridView */, 247 | ); 248 | }; 249 | /* End PBXProject section */ 250 | 251 | /* Begin PBXResourcesBuildPhase section */ 252 | 1D60588D0D05DD3D006BFB54 /* Resources */ = { 253 | isa = PBXResourcesBuildPhase; 254 | buildActionMask = 2147483647; 255 | files = ( 256 | 28AD733F0D9D9553002E5188 /* MainWindow.xib in Resources */, 257 | 2428E8D2112375660019252F /* DTSnapGridViewExampleCellView.xib in Resources */, 258 | 2428E8D3112375660019252F /* DTSnapGridViewExampleView.xib in Resources */, 259 | 2428E905112377B30019252F /* DTLicenseAgreementView.xib in Resources */, 260 | 2428E907112377B30019252F /* license.html in Resources */, 261 | 2428E919112379F10019252F /* Icon.png in Resources */, 262 | ); 263 | runOnlyForDeploymentPostprocessing = 0; 264 | }; 265 | /* End PBXResourcesBuildPhase section */ 266 | 267 | /* Begin PBXSourcesBuildPhase section */ 268 | 1D60588E0D05DD3D006BFB54 /* Sources */ = { 269 | isa = PBXSourcesBuildPhase; 270 | buildActionMask = 2147483647; 271 | files = ( 272 | 1D60589B0D05DD56006BFB54 /* main.m in Sources */, 273 | 1D3623260D0F684500981E51 /* DTGridViewAppDelegate.m in Sources */, 274 | 2428E8D0112375660019252F /* DTGridViewExampleDataSourceAndDelegate.m in Sources */, 275 | 2428E8D1112375660019252F /* DTInfiniteGridViewExampleViewController.m in Sources */, 276 | 2428E8D4112375660019252F /* DTSnapGridViewExampleViewController.m in Sources */, 277 | 2428E906112377B30019252F /* DTLicenseAgreementViewController.m in Sources */, 278 | 24388F8512B8D4F800848476 /* DTGridView.m in Sources */, 279 | 24388F8612B8D4F800848476 /* DTGridViewCell.m in Sources */, 280 | 24388F8712B8D4F800848476 /* DTGridViewController.m in Sources */, 281 | 24388F8812B8D4F800848476 /* DTInfiniteGridView.m in Sources */, 282 | 24388F8912B8D4F800848476 /* DTLabelsSnapGridViewCell.m in Sources */, 283 | 24388F8A12B8D4F800848476 /* DTSnapGridView.m in Sources */, 284 | 24388F8B12B8D4F800848476 /* DTSnapGridViewCell.m in Sources */, 285 | ); 286 | runOnlyForDeploymentPostprocessing = 0; 287 | }; 288 | /* End PBXSourcesBuildPhase section */ 289 | 290 | /* Begin XCBuildConfiguration section */ 291 | 1D6058940D05DD3E006BFB54 /* Debug */ = { 292 | isa = XCBuildConfiguration; 293 | buildSettings = { 294 | ALWAYS_SEARCH_USER_PATHS = NO; 295 | COPY_PHASE_STRIP = NO; 296 | GCC_DYNAMIC_NO_PIC = NO; 297 | GCC_OPTIMIZATION_LEVEL = 0; 298 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 299 | GCC_PREFIX_HEADER = DTGridView_Prefix.pch; 300 | INFOPLIST_FILE = "DTGridView-Info.plist"; 301 | PRODUCT_NAME = DTGridView; 302 | SDKROOT = iphoneos; 303 | }; 304 | name = Debug; 305 | }; 306 | 1D6058950D05DD3E006BFB54 /* Release */ = { 307 | isa = XCBuildConfiguration; 308 | buildSettings = { 309 | ALWAYS_SEARCH_USER_PATHS = NO; 310 | COPY_PHASE_STRIP = YES; 311 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 312 | GCC_PREFIX_HEADER = DTGridView_Prefix.pch; 313 | INFOPLIST_FILE = "DTGridView-Info.plist"; 314 | PRODUCT_NAME = DTGridView; 315 | }; 316 | name = Release; 317 | }; 318 | C01FCF4F08A954540054247B /* Debug */ = { 319 | isa = XCBuildConfiguration; 320 | buildSettings = { 321 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 322 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 323 | GCC_C_LANGUAGE_STANDARD = c99; 324 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 325 | GCC_WARN_UNUSED_VARIABLE = YES; 326 | "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; 327 | SDKROOT = iphoneos3.2; 328 | }; 329 | name = Debug; 330 | }; 331 | C01FCF5008A954540054247B /* Release */ = { 332 | isa = XCBuildConfiguration; 333 | buildSettings = { 334 | ARCHS = "$(ARCHS_STANDARD_32_BIT)"; 335 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 336 | GCC_C_LANGUAGE_STANDARD = c99; 337 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 338 | GCC_WARN_UNUSED_VARIABLE = YES; 339 | "PROVISIONING_PROFILE[sdk=iphoneos*]" = ""; 340 | SDKROOT = iphoneos; 341 | }; 342 | name = Release; 343 | }; 344 | /* End XCBuildConfiguration section */ 345 | 346 | /* Begin XCConfigurationList section */ 347 | 1D6058960D05DD3E006BFB54 /* Build configuration list for PBXNativeTarget "DTGridView" */ = { 348 | isa = XCConfigurationList; 349 | buildConfigurations = ( 350 | 1D6058940D05DD3E006BFB54 /* Debug */, 351 | 1D6058950D05DD3E006BFB54 /* Release */, 352 | ); 353 | defaultConfigurationIsVisible = 0; 354 | defaultConfigurationName = Release; 355 | }; 356 | C01FCF4E08A954540054247B /* Build configuration list for PBXProject "DTGridView" */ = { 357 | isa = XCConfigurationList; 358 | buildConfigurations = ( 359 | C01FCF4F08A954540054247B /* Debug */, 360 | C01FCF5008A954540054247B /* Release */, 361 | ); 362 | defaultConfigurationIsVisible = 0; 363 | defaultConfigurationName = Release; 364 | }; 365 | /* End XCConfigurationList section */ 366 | }; 367 | rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; 368 | } 369 | -------------------------------------------------------------------------------- /DTGridView Project/DTGridView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /DTGridView Project/DTGridView_Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'DTGridView' target in the 'DTGridView' project 3 | // 4 | 5 | #ifdef __OBJC__ 6 | #import 7 | #import 8 | #endif 9 | -------------------------------------------------------------------------------- /DTGridView Project/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/danielctull/DTGridView/925662ff650d1c000a06239435c921990a1da85b/DTGridView Project/Icon.png -------------------------------------------------------------------------------- /DTGridView Project/License Agreement/DTLicenseAgreementView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 528 5 | 10A402a 6 | 732 7 | 1030 8 | 431.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 58 12 | 13 | 14 | YES 15 | 16 | 17 | 18 | YES 19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 20 | 21 | 22 | YES 23 | 24 | YES 25 | 26 | 27 | YES 28 | 29 | 30 | 31 | YES 32 | 33 | IBFilesOwner 34 | 35 | 36 | IBFirstResponder 37 | 38 | 39 | 40 | 274 41 | 42 | YES 43 | 44 | 45 | 274 46 | {320, 480} 47 | 48 | 49 | 1 50 | MSAxIDEAA 51 | 52 | YES 53 | YES 54 | 1 55 | YES 56 | 57 | 58 | {320, 480} 59 | 60 | 61 | 3 62 | MQA 63 | 64 | 2 65 | 66 | 67 | 68 | 69 | 70 | 71 | YES 72 | 73 | 74 | view 75 | 76 | 77 | 78 | 4 79 | 80 | 81 | 82 | webView 83 | 84 | 85 | 86 | 5 87 | 88 | 89 | 90 | 91 | YES 92 | 93 | 0 94 | 95 | 96 | 97 | 98 | 99 | 1 100 | 101 | 102 | YES 103 | 104 | 105 | 106 | 107 | 108 | -1 109 | 110 | 111 | File's Owner 112 | 113 | 114 | -2 115 | 116 | 117 | 118 | 119 | 3 120 | 121 | 122 | 123 | 124 | 125 | 126 | YES 127 | 128 | YES 129 | -1.CustomClassName 130 | -2.CustomClassName 131 | 1.IBEditorWindowLastContentRect 132 | 1.IBPluginDependency 133 | 3.IBPluginDependency 134 | 135 | 136 | YES 137 | DTLicenseAgreementViewController 138 | UIResponder 139 | {{719, 315}, {320, 480}} 140 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 141 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 142 | 143 | 144 | 145 | YES 146 | 147 | 148 | YES 149 | 150 | 151 | 152 | 153 | YES 154 | 155 | 156 | YES 157 | 158 | 159 | 160 | 5 161 | 162 | 163 | 164 | YES 165 | 166 | DTLicenseAgreementViewController 167 | UIViewController 168 | 169 | webView 170 | UIWebView 171 | 172 | 173 | IBProjectSource 174 | DTLicenseAgreementViewController.h 175 | 176 | 177 | 178 | 179 | YES 180 | 181 | NSObject 182 | 183 | IBFrameworkSource 184 | Foundation.framework/Headers/NSError.h 185 | 186 | 187 | 188 | NSObject 189 | 190 | IBFrameworkSource 191 | Foundation.framework/Headers/NSFileManager.h 192 | 193 | 194 | 195 | NSObject 196 | 197 | IBFrameworkSource 198 | Foundation.framework/Headers/NSKeyValueCoding.h 199 | 200 | 201 | 202 | NSObject 203 | 204 | IBFrameworkSource 205 | Foundation.framework/Headers/NSKeyValueObserving.h 206 | 207 | 208 | 209 | NSObject 210 | 211 | IBFrameworkSource 212 | Foundation.framework/Headers/NSKeyedArchiver.h 213 | 214 | 215 | 216 | NSObject 217 | 218 | IBFrameworkSource 219 | Foundation.framework/Headers/NSNetServices.h 220 | 221 | 222 | 223 | NSObject 224 | 225 | IBFrameworkSource 226 | Foundation.framework/Headers/NSObject.h 227 | 228 | 229 | 230 | NSObject 231 | 232 | IBFrameworkSource 233 | Foundation.framework/Headers/NSPort.h 234 | 235 | 236 | 237 | NSObject 238 | 239 | IBFrameworkSource 240 | Foundation.framework/Headers/NSRunLoop.h 241 | 242 | 243 | 244 | NSObject 245 | 246 | IBFrameworkSource 247 | Foundation.framework/Headers/NSStream.h 248 | 249 | 250 | 251 | NSObject 252 | 253 | IBFrameworkSource 254 | Foundation.framework/Headers/NSThread.h 255 | 256 | 257 | 258 | NSObject 259 | 260 | IBFrameworkSource 261 | Foundation.framework/Headers/NSURL.h 262 | 263 | 264 | 265 | NSObject 266 | 267 | IBFrameworkSource 268 | Foundation.framework/Headers/NSURLConnection.h 269 | 270 | 271 | 272 | NSObject 273 | 274 | IBFrameworkSource 275 | Foundation.framework/Headers/NSXMLParser.h 276 | 277 | 278 | 279 | NSObject 280 | 281 | IBFrameworkSource 282 | UIKit.framework/Headers/UIAccessibility.h 283 | 284 | 285 | 286 | NSObject 287 | 288 | IBFrameworkSource 289 | UIKit.framework/Headers/UINibLoading.h 290 | 291 | 292 | 293 | NSObject 294 | 295 | IBFrameworkSource 296 | UIKit.framework/Headers/UIResponder.h 297 | 298 | 299 | 300 | UIResponder 301 | NSObject 302 | 303 | 304 | 305 | UISearchBar 306 | UIView 307 | 308 | IBFrameworkSource 309 | UIKit.framework/Headers/UISearchBar.h 310 | 311 | 312 | 313 | UISearchDisplayController 314 | NSObject 315 | 316 | IBFrameworkSource 317 | UIKit.framework/Headers/UISearchDisplayController.h 318 | 319 | 320 | 321 | UIView 322 | 323 | IBFrameworkSource 324 | UIKit.framework/Headers/UITextField.h 325 | 326 | 327 | 328 | UIView 329 | UIResponder 330 | 331 | IBFrameworkSource 332 | UIKit.framework/Headers/UIView.h 333 | 334 | 335 | 336 | UIViewController 337 | 338 | IBFrameworkSource 339 | UIKit.framework/Headers/UINavigationController.h 340 | 341 | 342 | 343 | UIViewController 344 | 345 | IBFrameworkSource 346 | UIKit.framework/Headers/UITabBarController.h 347 | 348 | 349 | 350 | UIViewController 351 | UIResponder 352 | 353 | IBFrameworkSource 354 | UIKit.framework/Headers/UIViewController.h 355 | 356 | 357 | 358 | UIWebView 359 | UIView 360 | 361 | IBFrameworkSource 362 | UIKit.framework/Headers/UIWebView.h 363 | 364 | 365 | 366 | 367 | 0 368 | 369 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 370 | 371 | 372 | 373 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 374 | 375 | 376 | 377 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 378 | 379 | 380 | YES 381 | DTKit.xcodeproj 382 | 3 383 | 3.0 384 | 385 | 386 | -------------------------------------------------------------------------------- /DTGridView Project/License Agreement/DTLicenseAgreementViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DTLicenseAgreementViewController.h 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 25.04.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | @interface DTLicenseAgreementViewController : UIViewController { 13 | UIWebView *webView; 14 | } 15 | 16 | @property (nonatomic, retain) IBOutlet UIWebView *webView; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /DTGridView Project/License Agreement/DTLicenseAgreementViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DTLicenseAgreementViewController.m 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 25.04.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import "DTLicenseAgreementViewController.h" 10 | 11 | 12 | @implementation DTLicenseAgreementViewController 13 | 14 | @synthesize webView; 15 | 16 | - (id)init { 17 | if (!(self = [self initWithNibName:@"DTLicenseAgreementView" bundle:nil])) 18 | return nil; 19 | 20 | self.title = @"Source License"; 21 | 22 | return self; 23 | } 24 | 25 | /* 26 | // Implement loadView to create a view hierarchy programmatically, without using a nib. 27 | - (void)loadView { 28 | } 29 | */ 30 | 31 | 32 | // Implement viewDidLoad to do additional setup after loading the view, typically from a nib. 33 | - (void)viewDidLoad { 34 | [super viewDidLoad]; 35 | NSString *webString = [NSString stringWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"license" ofType:@"html"] encoding:NSUTF8StringEncoding error:NULL]; 36 | [self.webView loadHTMLString:webString baseURL:nil]; 37 | } 38 | 39 | 40 | 41 | // Override to allow orientations other than the default portrait orientation. 42 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation { 43 | // Return YES for supported orientations 44 | return YES; //(interfaceOrientation == UIInterfaceOrientationPortrait); 45 | } 46 | 47 | - (void)didReceiveMemoryWarning { 48 | [super didReceiveMemoryWarning]; // Releases the view if it doesn't have a superview 49 | // Release anything that's not essential, such as cached data 50 | } 51 | 52 | 53 | - (void)dealloc { 54 | [webView release]; webView = nil; 55 | [super dealloc]; 56 | } 57 | 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /DTGridView Project/License Agreement/license.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | Source License 8 | 9 | 10 | 11 | 12 | 13 |
14 |

This is the license agreement for DTGridView. Don’t be too scared, you’re allowed to use it in your own products, commercial or otherwise.

15 |

The license text is further down this page, and you should only download and use the source code if you agree to the terms in that text. For convenience, though, I’ve put together a human-readable (as opposed to lawyer-readable) non-authoritative interpretation of the license which will hopefully answer any questions you have. Basically, the license says that:

16 |
    17 |
  1. You can use the code in your own products.
  2. 18 |
  3. You can modify the code as you wish, and use the modified code in your products.
  4. 19 |
  5. You can redistribute the original, unmodified code, but you have to include the full license text below.
  6. 20 |
  7. You can redistribute the modified code as you wish (without the full license text below).
  8. 21 |
  9. In all cases, you must include a credit mentioning Daniel Tull as the original author of the source.
  10. 22 |
  11. I’m not liable for anything you do with the code, no matter what. So be sensible.
  12. 23 |
  13. You can’t use my name or other marks to promote your products based on the code.
  14. 24 |
  15. If you agree to all of that, go ahead and download the source. Otherwise, don’t.
  16. 25 |
26 |

 

27 |

Suggested Attribution Format

28 |

The license requires that you give credit to me, Daniel Tull, as the original author of any of our source that you use. The placement and format of the credit is up to you, but I prefer the credit to be in the software’s “About” window. Alternatively, you could put the credit in the software’s documentation, or on the web page for the product. The suggested format for the attribution is:

29 |

30 | Includes DTGridView code by Daniel Tull. 31 |

32 |

Where possible, please link the text “Daniel Tull” to my address of my website (http://danieltull.co.uk/).

33 |

 

34 |

Full Source Code License Text

35 |

36 | License Agreement for Source Code provided by Daniel Tull

37 |

This software is supplied to you by Daniel Tull in consideration of your agreement to the following terms, and your use, installation, modification or redistribution of this software constitutes acceptance of these terms. If you do not agree with these terms, please do not use, install, modify or redistribute this software.

38 |

In consideration of your agreement to abide by the following terms, and subject to these terms, Daniel Tull grants you a personal, non-exclusive license, to use, reproduce, modify and redistribute the software, with or without modifications, in source and/or binary forms; provided that if you redistribute the software in its entirety and without modifications, you must retain this notice and the following text and disclaimers in all such redistributions of the software, and that in all cases attribution of Daniel Tull as the original author of the source code shall be included in all such resulting software products or distributions.
39 | Neither the name, trademarks, service marks or logos of Daniel Tull may be used to endorse or promote products derived from the software without specific prior written permission from Daniel Tull. Except as expressly stated in this notice, no other rights or licenses, express or implied, are granted by Daniel Tull herein, including but not limited to any patent rights that may be infringed by your derivative works or by other works in which the software may be incorporated.

40 |

The software is provided by Daniel Tull on an "AS IS" basis. DANIEL TULL MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, REGARDING THE SOFTWARE OR ITS USE AND OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS.

41 |

IN NO EVENT SHALL DANIEL TULL BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION AND/OR DISTRIBUTION OF THE SOFTWARE, HOWEVER CAUSED AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF DANIEL TULL HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 |

43 |

 

44 |

Other Questions?

45 |

If you’ve got any questions about the license, or if you want to discuss any special requirements or licensing, feel free get in touch - you can find my contact details on the web, I promise to get a web page with my details on as soon as possible.

46 |

Also, if you do use some of my source, I'd love to hear about what it's being used in. Apart from that, have fun!

47 |

PS. Thanks to Matt Gemmell for letting me use his license agreement.

48 |
49 |
50 | 51 | 52 | -------------------------------------------------------------------------------- /DTGridView Project/MainWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 784 5 | 10A394 6 | 732 7 | 1027.1 8 | 430.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 60 12 | 13 | 14 | YES 15 | 16 | 17 | 18 | YES 19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 20 | 21 | 22 | YES 23 | 24 | YES 25 | 26 | 27 | YES 28 | 29 | 30 | 31 | YES 32 | 33 | IBFilesOwner 34 | 35 | 36 | IBFirstResponder 37 | 38 | 39 | 40 | 41 | 1316 42 | 43 | {320, 480} 44 | 45 | 46 | 1 47 | MSAxIDEAA 48 | 49 | NO 50 | NO 51 | 52 | 53 | 54 | 55 | 56 | YES 57 | 58 | 59 | delegate 60 | 61 | 62 | 63 | 4 64 | 65 | 66 | 67 | window 68 | 69 | 70 | 71 | 5 72 | 73 | 74 | 75 | 76 | YES 77 | 78 | 0 79 | 80 | 81 | 82 | 83 | 84 | 2 85 | 86 | 87 | YES 88 | 89 | 90 | 91 | 92 | -1 93 | 94 | 95 | File's Owner 96 | 97 | 98 | 3 99 | 100 | 101 | 102 | 103 | -2 104 | 105 | 106 | 107 | 108 | 109 | 110 | YES 111 | 112 | YES 113 | -1.CustomClassName 114 | -2.CustomClassName 115 | 2.IBAttributePlaceholdersKey 116 | 2.IBEditorWindowLastContentRect 117 | 2.IBPluginDependency 118 | 3.CustomClassName 119 | 3.IBPluginDependency 120 | 121 | 122 | YES 123 | UIApplication 124 | UIResponder 125 | 126 | YES 127 | 128 | 129 | YES 130 | 131 | 132 | {{438, 320}, {320, 480}} 133 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 134 | DTGridViewAppDelegate 135 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 136 | 137 | 138 | 139 | YES 140 | 141 | 142 | YES 143 | 144 | 145 | 146 | 147 | YES 148 | 149 | 150 | YES 151 | 152 | 153 | 154 | 9 155 | 156 | 157 | 158 | YES 159 | 160 | DTGridViewAppDelegate 161 | NSObject 162 | 163 | window 164 | UIWindow 165 | 166 | 167 | IBProjectSource 168 | Classes/DTGridViewAppDelegate.h 169 | 170 | 171 | 172 | DTGridViewAppDelegate 173 | NSObject 174 | 175 | IBUserSource 176 | 177 | 178 | 179 | 180 | 181 | 0 182 | 183 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 184 | 185 | 186 | YES 187 | DTGridView.xcodeproj 188 | 3 189 | 3.1 190 | 191 | 192 | -------------------------------------------------------------------------------- /DTGridView Project/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // DTGridView 4 | // 5 | // Created by Daniel Tull on 10.02.2010. 6 | // Copyright Daniel Tull 2010. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) { 12 | 13 | NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; 14 | int retVal = UIApplicationMain(argc, argv, nil, nil); 15 | [pool release]; 16 | return retVal; 17 | } 18 | -------------------------------------------------------------------------------- /DTGridView.h: -------------------------------------------------------------------------------- 1 | // 2 | // DTGridView.h 3 | // GridViewTester 4 | // 5 | // Created by Daniel Tull on 05.12.2008. 6 | // Copyright 2008 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DTGridViewCell.h" 11 | 12 | /*! 13 | @enum DTGridViewScrollPosition 14 | @abstract Used to determine how to position a grid view cell on screen when scrolling to it. 15 | @constant DTGridViewScrollPositionNone Aligns the cell such that the shortest distance to display as much of the cell is used. 16 | @constant DTGridViewScrollPositionTopLeft Aligns the cell so that it is in the top left of the grid view. 17 | @constant DTGridViewScrollPositionTopCenter Aligns the cell so that it is in the top center of the grid view. 18 | @constant DTGridViewScrollPositionTopRight Aligns the cell so that it is in the top right of the grid view. 19 | @constant DTGridViewScrollPositionMiddleLeft Aligns the cell so that it is in the middle left of the grid view. 20 | @constant DTGridViewScrollPositionMiddleCenter Aligns the cell so that it is in the middle center of the grid view. 21 | @constant DTGridViewScrollPositionMiddleRight Aligns the cell so that it is in the middle right of the grid view. 22 | @constant DTGridViewScrollPositionBottomLeft Aligns the cell so that it is in the bottom left of the grid view. 23 | @constant DTGridViewScrollPositionBottomCenter Aligns the cell so that it is in the bottom center of the grid view. 24 | @constant DTGridViewScrollPositionBottomRight Aligns the cell so that it is in the bottom right of the grid view. 25 | @discussion In most cases you will want to use DTGridViewScrollPositionNone to just bring the cell to the screen using the quickest route. In the case where the cell is too big to display completely on screen, the position will still be used, in that the center aligned cells will have their middle in the center of the screen, with their edges outside the screen bounds equally as much. 26 | */ 27 | typedef enum { 28 | DTGridViewScrollPositionNone = 0, 29 | DTGridViewScrollPositionTopLeft, 30 | DTGridViewScrollPositionTopCenter, 31 | DTGridViewScrollPositionTopRight, 32 | DTGridViewScrollPositionMiddleLeft, 33 | DTGridViewScrollPositionMiddleCenter, 34 | DTGridViewScrollPositionMiddleRight, 35 | DTGridViewScrollPositionBottomLeft, 36 | DTGridViewScrollPositionBottomCenter, 37 | DTGridViewScrollPositionBottomRight 38 | } DTGridViewScrollPosition; 39 | 40 | /*! 41 | @enum DTGridViewEdge 42 | @abstract Categorizes beverages into groups of similar types. 43 | @constant DTGridViewEdgeTop Sweet, carbonated, non-alcoholic beverages. 44 | @constant DTGridViewEdgeBottom Sweet, carbonated, non-alcoholic beverages. 45 | @constant DTGridViewEdgeLeft Sweet, carbonated, non-alcoholic beverages. 46 | @constant DTGridViewEdgeRight Sweet, carbonated, non-alcoholic beverages. 47 | @discussion Extended discussion goes here. 48 | Lorem ipsum.... 49 | */ 50 | typedef enum { 51 | DTGridViewEdgeTop, 52 | DTGridViewEdgeBottom, 53 | DTGridViewEdgeLeft, 54 | DTGridViewEdgeRight 55 | } DTGridViewEdge; 56 | 57 | struct DTOutset { 58 | CGFloat top; 59 | CGFloat bottom; 60 | CGFloat left; 61 | CGFloat right; 62 | }; 63 | 64 | @class DTGridView; 65 | 66 | @protocol DTGridViewDelegate 67 | 68 | @optional 69 | /*! 70 | Called when the grid view loads. 71 | */ 72 | - (void)gridViewDidLoad:(DTGridView *)gridView; 73 | - (void)gridView:(DTGridView *)gridView selectionMadeAtRow:(NSInteger)rowIndex column:(NSInteger)columnIndex; 74 | - (void)gridView:(DTGridView *)gridView scrolledToEdge:(DTGridViewEdge)edge; 75 | - (void)pagedGridView:(DTGridView *)gridView didScrollToRow:(NSInteger)rowIndex column:(NSInteger)columnIndex; 76 | - (void)gridView:(DTGridView *)gridView didProgrammaticallyScrollToRow:(NSInteger)rowIndex column:(NSInteger)columnIndex; 77 | @end 78 | 79 | #pragma mark - 80 | 81 | @protocol DTGridViewDataSource 82 | /*! 83 | Asks the data source to return the number of rows in the grid view. 84 | The grid view object requesting this information. 85 | @return The number of rows in the grid view. 86 | */ 87 | - (NSInteger)numberOfRowsInGridView:(DTGridView *)gridView; 88 | /*! 89 | @abstract Asks the data source to return the number of columns for the given row in the grid view. 90 | @para The grid view object requesting this information. 91 | @para The index of the given row. 92 | @return The number of colums in the row of the grid view. 93 | */ 94 | - (NSInteger)numberOfColumnsInGridView:(DTGridView *)gridView forRowWithIndex:(NSInteger)index; 95 | - (CGFloat)gridView:(DTGridView *)gridView heightForRow:(NSInteger)rowIndex; 96 | - (CGFloat)gridView:(DTGridView *)gridView widthForCellAtRow:(NSInteger)rowIndex column:(NSInteger)columnIndex; 97 | - (DTGridViewCell *)gridView:(DTGridView *)gridView viewForRow:(NSInteger)rowIndex column:(NSInteger)columnIndex; 98 | 99 | @optional 100 | - (NSInteger)spacingBetweenRowsInGridView:(DTGridView *)gridView; 101 | - (NSInteger)spacingBetweenColumnsInGridView:(DTGridView *)gridView; 102 | 103 | @end 104 | 105 | #pragma mark - 106 | 107 | /*! 108 | @class DTGridView 109 | @abstract 110 | @discussion 111 | */ 112 | @interface DTGridView : UIScrollView { 113 | 114 | NSObject *dataSource; 115 | 116 | CGPoint cellOffset; 117 | 118 | UIEdgeInsets outset; 119 | 120 | NSMutableArray *gridCells; 121 | 122 | NSMutableArray *freeCells; 123 | NSMutableArray *cellInfoForCellsOnScreen; 124 | 125 | NSMutableArray *gridRows; 126 | NSMutableArray *rowHeights; 127 | NSMutableArray *rowPositions; 128 | 129 | NSMutableArray *cellsOnScreen; 130 | 131 | CGPoint oldContentOffset; 132 | BOOL hasResized; 133 | 134 | BOOL hasLoadedData; 135 | 136 | NSInteger numberOfRows; 137 | 138 | NSUInteger rowIndexOfSelectedCell; 139 | NSUInteger columnIndexOfSelectedCell; 140 | 141 | NSTimer *decelerationTimer; 142 | NSTimer *draggingTimer; 143 | } 144 | 145 | /*! 146 | @abstract The object that acts as the data source of the receiving grid view. 147 | @discussion The data source must adopt the DTGridViewDataSource protocol. The data source is not retained. 148 | */ 149 | @property (nonatomic, assign) IBOutlet NSObject *dataSource; 150 | 151 | /*! 152 | @abstract The object that acts as the delegate of the receiving grid view. 153 | @discussion The delegate must adopt the DTGridViewDelegate protocol. The delegate is not retained. 154 | */ 155 | @property (nonatomic, assign) IBOutlet id delegate; 156 | /*! 157 | @abstract The object that acts as the delegate of the receiving grid view. 158 | @deprecated This property is depricated and you should now use the standard delegate property. 159 | */ 160 | @property (nonatomic, assign) IBOutlet id gridDelegate; 161 | 162 | /*! 163 | @abstract The offset for each cell with respect to the cells above and to the right. 164 | @discussion The x and y values can be either positive or negative; Using negative will overlay the cells by that amount, the outcome of this can never be gauranteed what the ordering of cells will be though. 165 | */ 166 | @property (assign) CGPoint cellOffset; 167 | @property (assign) UIEdgeInsets outset; 168 | @property (nonatomic, retain) NSMutableArray *gridCells; 169 | @property (nonatomic) NSInteger numberOfRows; 170 | 171 | #pragma mark - 172 | #pragma mark Subclass methods 173 | 174 | // These methods can be overridden by subclasses. 175 | // They should never need to be called from outside classes. 176 | 177 | - (void)didEndMoving; 178 | - (void)didEndDragging; 179 | - (void)didEndDecelerating; 180 | 181 | - (CGFloat)findWidthForRow:(NSInteger)row column:(NSInteger)column; 182 | - (NSInteger)findNumberOfRows; 183 | - (NSInteger)findNumberOfColumnsForRow:(NSInteger)row; 184 | - (CGFloat)findHeightForRow:(NSInteger)row; 185 | - (DTGridViewCell *)findViewForRow:(NSInteger)row column:(NSInteger)column; 186 | 187 | #pragma mark - 188 | #pragma mark Regular methods 189 | /*! 190 | @abstract Returns a reusable grid view cell object located by its identifier. 191 | @param identifier A string identifying the cell object to be reused. 192 | @discussion For performance reasons, grid views should always reuse their cells. This works like the table view's reuse policy. 193 | */ 194 | - (DTGridViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier; 195 | 196 | /*! 197 | @abstract Returns a grid view cell object located by its row and column positions. 198 | @param rowIndex The index of the row of the wanted cell. 199 | @param columnIndex The index of the column of the wanted cell. 200 | @return The grid view cell of the grid or nil if the cell is not visible or the indexes is out of range. 201 | */ 202 | - (DTGridViewCell *)cellForRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex; 203 | 204 | /*! 205 | @abstract A constant that identifies a relative position in the receiving table view (top, middle, bottom) for row when scrolling concludes. See “Table View Scroll Position” a descriptions of valid constants. 206 | @param rowIndex The index of the row to scroll to. 207 | @param columnIndex The index of the column to scroll to. 208 | @param position The position the cell should be in once scrolled to. 209 | @param animated If this 210 | */ 211 | - (void)scrollViewToRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex scrollPosition:(DTGridViewScrollPosition)position animated:(BOOL)animated; 212 | 213 | - (void)selectRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex scrollPosition:(DTGridViewScrollPosition)position animated:(BOOL)animated; 214 | 215 | /*! 216 | @abstract This method should be used by subclasses to know when the grid did appear on screen. 217 | */ 218 | - (void)didLoad; 219 | 220 | /*! 221 | @abstract Call this to reload the grid view's data. 222 | */ 223 | - (void)reloadData; 224 | 225 | @end 226 | -------------------------------------------------------------------------------- /DTGridView.m: -------------------------------------------------------------------------------- 1 | // 2 | // DTGridView.m 3 | // GridViewTester 4 | // 5 | // Created by Daniel Tull on 05.12.2008. 6 | // Copyright 2008 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import "DTGridView.h" 10 | #import "DTGridViewCellInfoProtocol.h" 11 | 12 | NSInteger const DTGridViewInvalid = -1; 13 | 14 | 15 | @interface DTGridViewCellInfo : NSObject { 16 | NSUInteger xPosition, yPosition; 17 | CGRect frame; 18 | CGFloat x, y, width, height; 19 | } 20 | @property (nonatomic, assign) CGFloat x, y, width, height; 21 | @end 22 | 23 | @implementation DTGridViewCellInfo 24 | @synthesize xPosition, yPosition, x, y, width, height, frame; 25 | - (NSString *)description { 26 | return [NSString stringWithFormat:@"DTGridViewCellInfo: frame=(%i %i; %i %i) x=%i, y=%i", (NSInteger)self.frame.origin.x, (NSInteger)self.frame.origin.y, (NSInteger)self.frame.size.width, (NSInteger)self.frame.size.height, self.xPosition, self.yPosition]; 27 | } 28 | @end 29 | 30 | @interface DTGridView () 31 | - (void)dctInternal_setupInternals; 32 | - (void)loadData; 33 | - (void)checkViews; 34 | - (void)initialiseViews; 35 | - (void)fireEdgeScroll; 36 | - (void)checkNewRowStartingWithCellInfo:(NSObject *)info goingUp:(BOOL)goingUp; 37 | - (NSObject *)cellInfoForRow:(NSUInteger)row column:(NSUInteger)col; 38 | - (void)checkRow:(NSInteger)row column:(NSInteger)col goingLeft:(BOOL)goingLeft; 39 | 40 | 41 | - (void)decelerationTimer:(NSTimer *)timer; 42 | - (void)draggingTimer:(NSTimer *)timer; 43 | 44 | @property (nonatomic, retain) NSTimer *decelerationTimer, *draggingTimer; 45 | @end 46 | 47 | @implementation DTGridView 48 | 49 | @dynamic delegate; 50 | @synthesize dataSource, gridCells, numberOfRows, cellOffset, outset; 51 | @synthesize decelerationTimer, draggingTimer; 52 | 53 | - (void)dealloc { 54 | super.delegate = nil; 55 | self.dataSource = nil; 56 | [cellsOnScreen release], cellsOnScreen = nil; 57 | [gridRows release], gridRows = nil; 58 | [rowPositions release], rowPositions = nil; 59 | [rowHeights release], rowHeights = nil; 60 | [freeCells release], freeCells = nil; 61 | [cellInfoForCellsOnScreen release], cellInfoForCellsOnScreen = nil; 62 | [super dealloc]; 63 | } 64 | 65 | - (void)setGridDelegate:(id )aDelegate { 66 | self.delegate = aDelegate; 67 | } 68 | - (id )gridDelegate { 69 | return self.delegate; 70 | } 71 | 72 | NSInteger intSort(id info1, id info2, void *context) { 73 | 74 | DTGridViewCellInfo *i1 = (DTGridViewCellInfo *)info1; 75 | DTGridViewCellInfo *i2 = (DTGridViewCellInfo *)info2; 76 | 77 | if (i1.yPosition < i2.yPosition) 78 | return NSOrderedAscending; 79 | else if (i1.yPosition > i2.yPosition) 80 | return NSOrderedDescending; 81 | else if (i1.xPosition < i2.xPosition) 82 | return NSOrderedAscending; 83 | else if (i1.xPosition > i2.xPosition) 84 | return NSOrderedDescending; 85 | else 86 | return NSOrderedSame; 87 | } 88 | 89 | 90 | - (id)initWithFrame:(CGRect)frame { 91 | 92 | if (!(self = [super initWithFrame:frame])) return nil; 93 | 94 | [self dctInternal_setupInternals]; 95 | 96 | return self; 97 | 98 | } 99 | 100 | - (void)awakeFromNib { 101 | [self dctInternal_setupInternals]; 102 | } 103 | 104 | - (void)dctInternal_setupInternals { 105 | numberOfRows = DTGridViewInvalid; 106 | columnIndexOfSelectedCell = DTGridViewInvalid; 107 | rowIndexOfSelectedCell = DTGridViewInvalid; 108 | 109 | gridRows = [[NSMutableArray alloc] init]; 110 | rowPositions = [[NSMutableArray alloc] init]; 111 | rowHeights = [[NSMutableArray alloc] init]; 112 | cellsOnScreen = [[NSMutableArray alloc] init]; 113 | 114 | freeCells = [[NSMutableArray alloc] init]; 115 | 116 | cellInfoForCellsOnScreen = [[NSMutableArray alloc] init]; 117 | } 118 | 119 | - (void)setFrame:(CGRect)aFrame { 120 | 121 | CGSize oldSize = self.frame.size; 122 | CGSize newSize = aFrame.size; 123 | 124 | if (oldSize.height != newSize.height || oldSize.width != newSize.width) { 125 | hasResized = YES; 126 | } 127 | 128 | [super setFrame:aFrame]; 129 | 130 | if (hasResized) { 131 | [self setNeedsLayout]; 132 | } 133 | } 134 | 135 | - (void)reloadData { 136 | [self loadData]; 137 | [self setNeedsDisplay]; 138 | [self setNeedsLayout]; 139 | } 140 | 141 | - (void)drawRect:(CGRect)rect { 142 | 143 | oldContentOffset = CGPointMake(0.0f, 0.0f); 144 | 145 | //hasLoadedData = NO; 146 | 147 | //if (!hasLoadedData) 148 | 149 | [self loadData]; 150 | 151 | for (UIView *v in self.subviews) 152 | if ([v isKindOfClass:[DTGridViewCell class]]) 153 | [v removeFromSuperview]; 154 | 155 | [self initialiseViews]; 156 | 157 | [self didLoad]; 158 | } 159 | 160 | - (void)didLoad { 161 | if ([self.delegate respondsToSelector:@selector(gridViewDidLoad:)]) 162 | [self.delegate gridViewDidLoad:self]; 163 | } 164 | 165 | - (void)didEndDragging {} 166 | - (void)didEndDecelerating {} 167 | - (void)didEndMoving {} 168 | 169 | - (void)layoutSubviews { 170 | [super layoutSubviews]; 171 | [self checkViews]; 172 | [self fireEdgeScroll]; 173 | 174 | if (!self.draggingTimer && !self.decelerationTimer && self.dragging) 175 | self.draggingTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(draggingTimer:) userInfo:nil repeats:NO]; 176 | 177 | if (!self.decelerationTimer && self.decelerating) { 178 | self.decelerationTimer = [NSTimer scheduledTimerWithTimeInterval:0.0 target:self selector:@selector(decelerationTimer:) userInfo:nil repeats:NO]; 179 | [self.draggingTimer invalidate]; 180 | self.draggingTimer = nil; 181 | } 182 | } 183 | 184 | - (void)decelerationTimer:(NSTimer *)timer { 185 | self.decelerationTimer = nil; 186 | [self didEndDecelerating]; 187 | [self didEndMoving]; 188 | } 189 | 190 | - (void)draggingTimer:(NSTimer *)timer { 191 | self.draggingTimer = nil; 192 | [self didEndDragging]; 193 | [self didEndMoving]; 194 | } 195 | 196 | #pragma mark Adding and Removing Cells 197 | 198 | - (void)addCellWithInfo:(NSObject *)info { 199 | 200 | if (![info isMemberOfClass:[DTGridViewCellInfo class]]) return; 201 | 202 | [cellInfoForCellsOnScreen addObject:info]; 203 | 204 | [cellInfoForCellsOnScreen sortUsingFunction:intSort context:NULL]; 205 | 206 | DTGridViewCell *cell = [[self findViewForRow:info.yPosition column:info.xPosition] retain]; 207 | [cell setNeedsDisplay]; 208 | cell.xPosition = info.xPosition; 209 | cell.yPosition = info.yPosition; 210 | cell.delegate = self; 211 | cell.frame = info.frame; 212 | 213 | if (cell.xPosition == columnIndexOfSelectedCell && cell.yPosition == rowIndexOfSelectedCell) 214 | cell.selected = YES; 215 | else 216 | cell.selected = NO; 217 | 218 | [[gridCells objectAtIndex:info.yPosition] replaceObjectAtIndex:info.xPosition withObject:cell]; 219 | 220 | [self insertSubview:cell atIndex:0]; 221 | 222 | // remove any existing view at this frame 223 | for (UIView *v in self.subviews) { 224 | if ([v isKindOfClass:[DTGridViewCell class]] && 225 | v.frame.origin.x == cell.frame.origin.x && 226 | v.frame.origin.y == cell.frame.origin.y && 227 | v != cell) { 228 | 229 | [v removeFromSuperview]; 230 | break; 231 | } 232 | } 233 | 234 | [cell release]; 235 | 236 | } 237 | 238 | - (void)removeCellWithInfo:(DTGridViewCellInfo *)info { 239 | 240 | 241 | 242 | if (info.yPosition > [gridCells count]) return; 243 | 244 | NSMutableArray *row = [gridCells objectAtIndex:info.yPosition]; 245 | 246 | if (info.xPosition > [row count]) return; 247 | 248 | DTGridViewCell *cell = [row objectAtIndex:info.xPosition]; 249 | 250 | if (![cell isKindOfClass:[DTGridViewCell class]]) return; 251 | 252 | [cell retain]; 253 | 254 | [cell removeFromSuperview]; 255 | 256 | [row replaceObjectAtIndex:info.xPosition withObject:info]; 257 | 258 | [cellInfoForCellsOnScreen removeObject:info]; 259 | 260 | // TODO: Should this be set? 261 | //cell.frame = CGRectZero; 262 | 263 | [freeCells addObject:cell]; 264 | 265 | [cell release]; 266 | } 267 | 268 | - (CGRect)visibleRect { 269 | CGRect visibleRect; 270 | visibleRect.origin = self.contentOffset; 271 | visibleRect.size = self.bounds.size; 272 | return visibleRect; 273 | } 274 | 275 | - (BOOL)rowOfCellInfoShouldBeOnShow:(NSObject *)info { 276 | 277 | CGRect visibleRect = [self visibleRect]; 278 | 279 | CGRect infoFrame = info.frame; 280 | 281 | CGFloat infoBottom = infoFrame.origin.y + infoFrame.size.height; 282 | CGFloat infoTop = infoFrame.origin.y; 283 | 284 | CGFloat visibleBottom = visibleRect.origin.y + visibleRect.size.height; 285 | CGFloat visibleTop = visibleRect.origin.y; 286 | 287 | return (infoBottom >= visibleTop && 288 | infoTop <= visibleBottom); 289 | } 290 | 291 | - (BOOL)cellInfoShouldBeOnShow:(NSObject *)info { 292 | 293 | if (!info || ![info isMemberOfClass:[DTGridViewCellInfo class]]) return NO; 294 | 295 | CGRect visibleRect = [self visibleRect]; 296 | 297 | CGFloat infoRight = info.frame.origin.x + info.frame.size.width; 298 | CGFloat infoLeft = info.frame.origin.x; 299 | 300 | CGFloat visibleRight = visibleRect.origin.x + visibleRect.size.width; 301 | CGFloat visibleLeft = visibleRect.origin.x; 302 | 303 | if (infoRight >= visibleLeft && 304 | infoLeft <= visibleRight && 305 | [self rowOfCellInfoShouldBeOnShow:info]) return YES; 306 | 307 | //NSLog(@"%@ NO: %@", NSStringFromSelector(_cmd), NSStringFromCGRect(info.frame)); 308 | 309 | return NO; 310 | } 311 | 312 | 313 | #pragma mark - 314 | #pragma mark Finding Infomation from DataSource 315 | 316 | - (CGFloat)findWidthForRow:(NSInteger)row column:(NSInteger)column { 317 | return [self.dataSource gridView:self widthForCellAtRow:row column:column]; 318 | } 319 | 320 | - (NSInteger)findNumberOfRows { 321 | return [self.dataSource numberOfRowsInGridView:self]; 322 | } 323 | 324 | - (NSInteger)findNumberOfColumnsForRow:(NSInteger)row { 325 | return [self.dataSource numberOfColumnsInGridView:self forRowWithIndex:row]; 326 | } 327 | 328 | - (CGFloat)findHeightForRow:(NSInteger)row { 329 | return [self.dataSource gridView:self heightForRow:row]; 330 | } 331 | 332 | - (DTGridViewCell *)findViewForRow:(NSInteger)row column:(NSInteger)column { 333 | return [self.dataSource gridView:self viewForRow:row column:column]; 334 | } 335 | #pragma mark - 336 | 337 | - (void)loadData { 338 | 339 | hasLoadedData = YES; 340 | 341 | if (![self.dataSource respondsToSelector:@selector(numberOfRowsInGridView:)]) 342 | return; 343 | 344 | self.numberOfRows = [self findNumberOfRows]; 345 | 346 | if (!self.numberOfRows) 347 | return; 348 | 349 | [gridRows removeAllObjects]; 350 | [rowHeights removeAllObjects]; 351 | [rowPositions removeAllObjects]; 352 | 353 | NSMutableArray *cellInfoArrayRows = [[NSMutableArray alloc] init]; 354 | 355 | CGFloat maxHeight = 0; 356 | CGFloat maxWidth = 0; 357 | 358 | 359 | for (NSInteger i = 0; i < self.numberOfRows; i++) { 360 | 361 | NSInteger numberOfCols = [self findNumberOfColumnsForRow:i]; 362 | 363 | NSMutableArray *cellInfoArrayCols = [[NSMutableArray alloc] init]; 364 | 365 | for (NSInteger j = 0; j < numberOfCols; j++) { 366 | 367 | 368 | DTGridViewCellInfo *info = [[DTGridViewCellInfo alloc] init]; 369 | 370 | info.xPosition = j; 371 | info.yPosition = i; 372 | 373 | 374 | CGFloat height = [self findHeightForRow:i]; 375 | CGFloat width = [self findWidthForRow:i column:j]; 376 | 377 | //info.frame.size.height = [dataSource gridView:self heightForRow:i]; 378 | //info.frame.size.width = [dataSource gridView:self widthForCellAtRow:i column:j]; 379 | CGFloat y; 380 | CGFloat x; 381 | 382 | if (i == 0) { 383 | y = 0.0f; 384 | //info.frame.origin.y = 0.0; 385 | } else { 386 | DTGridViewCellInfo *previousCellRow = [[cellInfoArrayRows objectAtIndex:i-1] objectAtIndex:0]; 387 | y = previousCellRow.frame.origin.y + previousCellRow.frame.size.height; 388 | 389 | if (cellOffset.y != 0) 390 | y += cellOffset.y; 391 | } 392 | 393 | if (j == 0) { 394 | x = 0.0f; 395 | } else { 396 | DTGridViewCellInfo *previousCellRow = [cellInfoArrayCols objectAtIndex:j-1]; 397 | x = previousCellRow.frame.origin.x + previousCellRow.frame.size.width; 398 | if (cellOffset.x != 0) 399 | x += cellOffset.x; 400 | } 401 | 402 | if (maxHeight < y + height) 403 | maxHeight = y + height; 404 | 405 | if (maxWidth < x + width) 406 | maxWidth = x + width; 407 | 408 | info.frame = CGRectMake(x,y,width,height); 409 | 410 | [cellInfoArrayCols addObject:info]; 411 | 412 | [info release]; 413 | } 414 | 415 | [cellInfoArrayRows addObject:cellInfoArrayCols]; 416 | [cellInfoArrayCols release]; 417 | } 418 | 419 | 420 | self.contentSize = CGSizeMake(maxWidth, maxHeight); 421 | 422 | self.gridCells = cellInfoArrayRows; 423 | [cellInfoArrayRows release]; 424 | 425 | if ([self.subviews count] > [self.gridCells count]) { 426 | // the underlying data must have reduced, time to iterate 427 | NSSet *gridCellsSet = [NSSet setWithArray:self.gridCells]; 428 | NSArray *subviewsCopy = [self.subviews copy]; 429 | 430 | for (UIView *cell in subviewsCopy) { 431 | if ( 432 | [cell isKindOfClass:[DTGridViewCell class]] && 433 | ![gridCellsSet member:cell] 434 | ) 435 | { 436 | [cell removeFromSuperview]; 437 | } 438 | } 439 | 440 | [subviewsCopy release]; 441 | } 442 | } 443 | 444 | - (void)checkViews { 445 | 446 | if ([cellInfoForCellsOnScreen count] == 0) { 447 | [self initialiseViews]; 448 | return; 449 | } 450 | 451 | NSMutableDictionary *leftRightCells = [[NSMutableDictionary alloc] init]; 452 | 453 | NSArray *orderedCells = [cellInfoForCellsOnScreen copy]; 454 | 455 | BOOL isGoingUp = NO; 456 | BOOL isGoingDown = NO; 457 | BOOL isGoingLeft = NO; 458 | BOOL isGoingRight = NO; 459 | 460 | if (self.contentOffset.y < oldContentOffset.y && self.contentOffset.y >= 0) 461 | isGoingUp = YES; 462 | else if (self.contentOffset.y > oldContentOffset.y && self.contentOffset.y + self.frame.size.height < self.contentSize.height) 463 | isGoingDown = YES; 464 | else if (hasResized) 465 | isGoingUp = YES; 466 | 467 | if (self.contentOffset.x < oldContentOffset.x && self.contentOffset.x >= 0) 468 | isGoingLeft = YES; 469 | else if (self.contentOffset.x > oldContentOffset.x && self.contentOffset.x + self.frame.size.width < self.contentSize.width) 470 | isGoingRight = YES; 471 | else if (hasResized) 472 | isGoingRight = YES; 473 | 474 | // NSLog(@"isGoingUp: %i, isGoingDown: %i, co.y: %f, old.y: %f", isGoingUp, isGoingDown, self.contentOffset.y, oldContentOffset.y); 475 | 476 | hasResized = NO; 477 | oldContentOffset = self.contentOffset; 478 | 479 | for (DTGridViewCellInfo *info in orderedCells) { 480 | 481 | if (isGoingLeft) { 482 | if (info.xPosition > 0 && info.frame.origin.x > self.contentOffset.x) { 483 | if (![leftRightCells objectForKey:[NSString stringWithFormat:@"%i", info.yPosition]]) 484 | [leftRightCells setObject:info forKey:[NSString stringWithFormat:@"%i", info.yPosition]]; 485 | else if ([[leftRightCells objectForKey:[NSString stringWithFormat:@"%i", info.yPosition]] xPosition] > info.xPosition) 486 | [leftRightCells setObject:info forKey:[NSString stringWithFormat:@"%i", info.yPosition]]; 487 | } 488 | } else if (isGoingRight) { 489 | if ([[self.gridCells objectAtIndex:info.yPosition] count] - 1 > info.xPosition && info.frame.origin.x + info.frame.size.width < self.contentOffset.x + self.frame.size.width) { 490 | if (![leftRightCells objectForKey:[NSString stringWithFormat:@"%i", info.yPosition]]) 491 | [leftRightCells setObject:info forKey:[NSString stringWithFormat:@"%i", info.yPosition]]; 492 | else if ([[leftRightCells objectForKey:[NSString stringWithFormat:@"%i", info.yPosition]] xPosition] < info.xPosition) 493 | [leftRightCells setObject:info forKey:[NSString stringWithFormat:@"%i", info.yPosition]]; 494 | } 495 | } 496 | 497 | if (![self cellInfoShouldBeOnShow:info]) 498 | [self removeCellWithInfo:info]; 499 | 500 | } 501 | 502 | if (isGoingLeft) { 503 | for (NSString *yPos in [leftRightCells allKeys]) { 504 | DTGridViewCellInfo *info = [leftRightCells objectForKey:yPos]; 505 | [self checkRow:info.yPosition column:info.xPosition goingLeft:YES]; 506 | } 507 | 508 | } else if (isGoingRight) { 509 | for (NSString *yPos in [leftRightCells allKeys]) { 510 | DTGridViewCellInfo *info = [leftRightCells objectForKey:yPos]; 511 | [self checkRow:info.yPosition column:info.xPosition goingLeft:NO]; 512 | } 513 | } 514 | 515 | if (isGoingUp) 516 | [self checkNewRowStartingWithCellInfo:[orderedCells objectAtIndex:0] goingUp:YES]; 517 | else if (isGoingDown) 518 | [self checkNewRowStartingWithCellInfo:[orderedCells lastObject] goingUp:NO]; 519 | 520 | 521 | [leftRightCells release]; 522 | [orderedCells release]; 523 | } 524 | 525 | - (void)initialiseViews { 526 | 527 | for (NSUInteger i = 0; i < [cellInfoForCellsOnScreen count]; i++) { 528 | 529 | DTGridViewCellInfo *info = [cellInfoForCellsOnScreen objectAtIndex:i]; 530 | 531 | if (![self cellInfoShouldBeOnShow:info]) 532 | [self removeCellWithInfo:info]; 533 | 534 | } 535 | 536 | for (NSUInteger i = 0; i < [gridCells count]; i++) { 537 | 538 | NSMutableArray *row = [gridCells objectAtIndex:i]; 539 | 540 | for (NSUInteger j = 0; j < [row count]; j++) { 541 | 542 | id object = [row objectAtIndex:j]; 543 | 544 | if ([object isMemberOfClass:[DTGridViewCellInfo class]]) { 545 | 546 | DTGridViewCellInfo *info = (DTGridViewCellInfo *)object; 547 | 548 | if ([self cellInfoShouldBeOnShow:info]) 549 | [self addCellWithInfo:info]; 550 | 551 | } 552 | } 553 | } 554 | } 555 | 556 | - (void)checkRow:(NSInteger)row column:(NSInteger)col goingLeft:(BOOL)goingLeft { 557 | 558 | NSObject *info = [self cellInfoForRow:row column:col]; 559 | 560 | if (!info) return; 561 | 562 | if ([self cellInfoShouldBeOnShow:info]) 563 | [self addCellWithInfo:info]; 564 | 565 | if (goingLeft) { 566 | if (info.frame.origin.x > self.contentOffset.x) 567 | [self checkRow:row column:(col - 1) goingLeft:goingLeft]; 568 | } else { 569 | if (info.frame.origin.x + info.frame.size.width < self.contentOffset.x + self.frame.size.width) 570 | [self checkRow:row column:(col + 1) goingLeft:goingLeft]; 571 | } 572 | } 573 | 574 | - (NSObject *)cellInfoForRow:(NSUInteger)row column:(NSUInteger)col { 575 | 576 | if ([self.gridCells count] <= row) return nil; 577 | 578 | NSArray *rowArray = [self.gridCells objectAtIndex:row]; 579 | 580 | if ([rowArray count] <= col) return nil; 581 | 582 | return (NSObject *)[rowArray objectAtIndex:col]; 583 | } 584 | 585 | - (void)checkNewRowStartingWithCellInfo:(NSObject *)info goingUp:(BOOL)goingUp { 586 | 587 | //NSLog(@"%@", info); 588 | 589 | if (!info) return; 590 | 591 | if (![self rowOfCellInfoShouldBeOnShow:info]) return; 592 | 593 | NSObject *infoToCheck = info; 594 | 595 | NSInteger row = info.yPosition; 596 | NSInteger total = [[self.gridCells objectAtIndex:row] count]; 597 | NSInteger goingRightPosition = info.xPosition; 598 | NSInteger goingLeftPosition = info.xPosition; 599 | BOOL goingLeft = NO; 600 | 601 | while (![self cellInfoShouldBeOnShow:infoToCheck]) { 602 | 603 | goingLeft = !goingLeft; 604 | 605 | if (goingLeft) 606 | infoToCheck = [self cellInfoForRow:row column:--goingLeftPosition]; 607 | else 608 | infoToCheck = [self cellInfoForRow:row column:++goingRightPosition]; 609 | 610 | if (goingRightPosition > total) 611 | return; 612 | } 613 | 614 | if ([infoToCheck isEqual:info]) { 615 | [self checkRow:infoToCheck.yPosition column:infoToCheck.xPosition goingLeft:YES]; 616 | [self checkRow:infoToCheck.yPosition column:infoToCheck.xPosition goingLeft:NO]; 617 | } else { 618 | [self checkRow:infoToCheck.yPosition column:infoToCheck.xPosition goingLeft:goingLeft]; 619 | } 620 | 621 | NSObject *nextInfo = nil; 622 | 623 | if (goingUp) 624 | nextInfo = [self cellInfoForRow:info.yPosition - 1 column:info.xPosition]; 625 | else 626 | nextInfo = [self cellInfoForRow:info.yPosition + 1 column:info.xPosition]; 627 | 628 | if (nextInfo) 629 | [self checkNewRowStartingWithCellInfo:nextInfo goingUp:goingUp]; 630 | } 631 | 632 | #pragma mark Public methods 633 | 634 | - (DTGridViewCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier { 635 | 636 | for (DTGridViewCell *c in freeCells) { 637 | if ([c.identifier isEqualToString:identifier]) { 638 | [c retain]; 639 | [freeCells removeObject:c]; 640 | [c prepareForReuse]; 641 | return [c autorelease]; 642 | } 643 | } 644 | 645 | return nil; 646 | } 647 | 648 | - (DTGridViewCell *)cellForRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex { 649 | 650 | for (UIView *v in self.subviews) { 651 | if ([v isKindOfClass:[DTGridViewCell class]]) { 652 | DTGridViewCell *c = (DTGridViewCell *)v; 653 | if (c.xPosition == columnIndex && c.yPosition == rowIndex) 654 | return c; 655 | } 656 | } 657 | 658 | return nil; 659 | } 660 | 661 | - (void)scrollViewToRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex scrollPosition:(DTGridViewScrollPosition)position animated:(BOOL)animated { 662 | 663 | CGFloat xPos = 0, yPos = 0; 664 | 665 | CGRect cellFrame = [[[self.gridCells objectAtIndex:rowIndex] objectAtIndex:columnIndex] frame]; 666 | 667 | // working out x co-ord 668 | 669 | if (position == DTGridViewScrollPositionTopLeft || position == DTGridViewScrollPositionMiddleLeft || position == DTGridViewScrollPositionBottomLeft) 670 | xPos = cellFrame.origin.x; 671 | 672 | else if (position == DTGridViewScrollPositionTopRight || position == DTGridViewScrollPositionMiddleRight || position == DTGridViewScrollPositionBottomRight) 673 | xPos = cellFrame.origin.x + cellFrame.size.width - self.frame.size.width; 674 | 675 | else if (position == DTGridViewScrollPositionTopCenter || position == DTGridViewScrollPositionMiddleCenter || position == DTGridViewScrollPositionBottomCenter) 676 | xPos = (cellFrame.origin.x + (cellFrame.size.width / 2)) - (self.frame.size.width / 2); 677 | 678 | else if (position == DTGridViewScrollPositionNone) { 679 | 680 | BOOL isBig = NO; 681 | 682 | if (cellFrame.size.width > self.frame.size.width) 683 | isBig = YES; 684 | 685 | if ((cellFrame.origin.x < self.contentOffset.x) 686 | && ((cellFrame.origin.x + cellFrame.size.width) > (self.contentOffset.x + self.frame.size.width))) 687 | xPos = self.contentOffset.x; 688 | 689 | else if (cellFrame.origin.x < self.contentOffset.x) 690 | if (isBig) 691 | xPos = (cellFrame.origin.x + cellFrame.size.width) - self.frame.size.width; 692 | else 693 | xPos = cellFrame.origin.x; 694 | 695 | else if ((cellFrame.origin.x + cellFrame.size.width) > (self.contentOffset.x + self.frame.size.width)) 696 | if (isBig) 697 | xPos = cellFrame.origin.x; 698 | else 699 | xPos = (cellFrame.origin.x + cellFrame.size.width) - self.frame.size.width; 700 | else 701 | xPos = self.contentOffset.x; 702 | } 703 | 704 | // working out y co-ord 705 | 706 | if (position == DTGridViewScrollPositionTopLeft || position == DTGridViewScrollPositionTopCenter || position == DTGridViewScrollPositionTopRight) { 707 | yPos = cellFrame.origin.y; 708 | 709 | } else if (position == DTGridViewScrollPositionBottomLeft || position == DTGridViewScrollPositionBottomCenter || position == DTGridViewScrollPositionBottomRight) { 710 | yPos = cellFrame.origin.y + cellFrame.size.height - self.frame.size.height; 711 | 712 | } else if (position == DTGridViewScrollPositionMiddleLeft || position == DTGridViewScrollPositionMiddleCenter || position == DTGridViewScrollPositionMiddleRight) { 713 | yPos = (cellFrame.origin.y + (cellFrame.size.height / 2)) - (self.frame.size.height / 2); 714 | 715 | } else if (position == DTGridViewScrollPositionNone) { 716 | BOOL isBig = NO; 717 | 718 | if (cellFrame.size.height > self.frame.size.height) 719 | isBig = YES; 720 | 721 | if ((cellFrame.origin.y < self.contentOffset.y) 722 | && ((cellFrame.origin.y + cellFrame.size.height) > (self.contentOffset.y + self.frame.size.height))) 723 | yPos = self.contentOffset.y; 724 | 725 | else if (cellFrame.origin.y < self.contentOffset.y) 726 | if (isBig) 727 | yPos = (cellFrame.origin.y + cellFrame.size.height) - self.frame.size.height; 728 | else 729 | yPos = cellFrame.origin.y; 730 | else if ((cellFrame.origin.y + cellFrame.size.height) > (self.contentOffset.y + self.frame.size.height)) 731 | if (isBig) 732 | yPos = cellFrame.origin.y; 733 | else 734 | yPos = (cellFrame.origin.y + cellFrame.size.height) - self.frame.size.height; 735 | else 736 | yPos = self.contentOffset.y; 737 | } 738 | 739 | if (xPos == self.contentOffset.x && yPos == self.contentOffset.y) 740 | return; 741 | 742 | if (xPos > self.contentSize.width - self.frame.size.width) 743 | xPos = self.contentSize.width - self.frame.size.width; 744 | else if (xPos < 0) 745 | xPos = 0.0f; 746 | 747 | if (yPos > self.contentSize.height - self.frame.size.height) 748 | yPos = self.contentSize.height - self.frame.size.height; 749 | else if (yPos < 0) 750 | yPos = 0.0f; 751 | 752 | [self scrollRectToVisible:CGRectMake(xPos, yPos, self.frame.size.width, self.frame.size.height) animated:animated]; 753 | 754 | if (!animated) 755 | [self checkViews]; 756 | 757 | if ([self.delegate respondsToSelector:@selector(gridView:didProgrammaticallyScrollToRow:column:)]) 758 | [self.delegate gridView:self didProgrammaticallyScrollToRow:rowIndex column:columnIndex]; 759 | 760 | 761 | } 762 | 763 | - (void)selectRow:(NSUInteger)rowIndex column:(NSUInteger)columnIndex scrollPosition:(DTGridViewScrollPosition)position animated:(BOOL)animated { 764 | 765 | for (UIView *v in self.subviews) { 766 | if ([v isKindOfClass:[DTGridViewCell class]]) { 767 | DTGridViewCell *c = (DTGridViewCell *)v; 768 | if (c.xPosition == columnIndex && c.yPosition == rowIndex) 769 | c.selected = YES; 770 | else if (c.xPosition == columnIndexOfSelectedCell && c.yPosition == rowIndexOfSelectedCell) 771 | c.selected = NO; 772 | } 773 | } 774 | rowIndexOfSelectedCell = rowIndex; 775 | columnIndexOfSelectedCell = columnIndex; 776 | 777 | [self scrollViewToRow:rowIndex column:columnIndex scrollPosition:position animated:animated]; 778 | } 779 | 780 | - (void)fireEdgeScroll { 781 | 782 | if (self.pagingEnabled) 783 | if ([self.delegate respondsToSelector:@selector(pagedGridView:didScrollToRow:column:)]) 784 | [self.delegate pagedGridView:self didScrollToRow:((NSInteger)(self.contentOffset.y / self.frame.size.height)) column:((NSInteger)(self.contentOffset.x / self.frame.size.width))]; 785 | 786 | if ([self.delegate respondsToSelector:@selector(gridView:scrolledToEdge:)]) { 787 | 788 | if (self.contentOffset.x <= 0) 789 | [self.delegate gridView:self scrolledToEdge:DTGridViewEdgeLeft]; 790 | 791 | if (self.contentOffset.x >= self.contentSize.width - self.frame.size.width) 792 | [self.delegate gridView:self scrolledToEdge:DTGridViewEdgeRight]; 793 | 794 | if (self.contentOffset.y <= 0) 795 | [self.delegate gridView:self scrolledToEdge:DTGridViewEdgeTop]; 796 | 797 | if (self.contentOffset.y >= self.contentSize.height - self.frame.size.height) 798 | [self.delegate gridView:self scrolledToEdge:DTGridViewEdgeBottom]; 799 | } 800 | } 801 | 802 | - (void)gridViewCellWasTouched:(DTGridViewCell *)cell { 803 | 804 | [self bringSubviewToFront:cell]; 805 | 806 | if ([self.delegate respondsToSelector:@selector(gridView:selectionMadeAtRow:column:)]) 807 | [self.delegate gridView:self selectionMadeAtRow:cell.yPosition column:cell.xPosition]; 808 | } 809 | 810 | 811 | #pragma mark - 812 | #pragma mark Accessors 813 | 814 | - (NSInteger)numberOfRows { 815 | if (numberOfRows == DTGridViewInvalid) { 816 | numberOfRows = [self.dataSource numberOfRowsInGridView:self]; 817 | } 818 | 819 | return numberOfRows; 820 | } 821 | 822 | @end 823 | 824 | -------------------------------------------------------------------------------- /DTGridViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // DTGridViewCell.h 3 | // GridViewTester 4 | // 5 | // Created by Daniel Tull on 06.04.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DTGridViewCellInfoProtocol.h" 11 | 12 | @protocol DTGridViewCellDelegate; 13 | 14 | /*! 15 | @class DTGridViewCell 16 | @abstract 17 | @discussion 18 | */ 19 | @interface DTGridViewCell : UIView { 20 | 21 | NSUInteger xPosition, yPosition; 22 | NSString *identifier; 23 | 24 | BOOL selected; 25 | BOOL highlighted; 26 | 27 | id delegate; 28 | 29 | } 30 | @property (nonatomic, assign) id delegate; 31 | @property (nonatomic, copy) NSString *identifier; 32 | @property (nonatomic, assign) BOOL selected; 33 | @property (nonatomic, assign) BOOL highlighted; 34 | - (id)initWithReuseIdentifier:(NSString *)identifier; 35 | - (void)prepareForReuse; 36 | @end 37 | 38 | @protocol DTGridViewCellDelegate 39 | 40 | -(void)gridViewCellWasTouched:(DTGridViewCell *)gridViewCell; 41 | 42 | @end 43 | -------------------------------------------------------------------------------- /DTGridViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // DTGridViewCell.m 3 | // GridViewTester 4 | // 5 | // Created by Daniel Tull on 06.04.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import "DTGridViewCell.h" 10 | #import "DTGridView.h" 11 | 12 | #pragma mark Private Methods 13 | @interface DTGridViewCell () 14 | - (DTGridView *)gridView; 15 | @end 16 | 17 | 18 | 19 | @implementation DTGridViewCell 20 | 21 | @synthesize xPosition, yPosition, identifier, delegate, selected; 22 | @synthesize highlighted; 23 | 24 | @dynamic frame; 25 | 26 | - (id)initWithReuseIdentifier:(NSString *)anIdentifier { 27 | 28 | if (![super initWithFrame:CGRectZero]) 29 | return nil; 30 | 31 | identifier = [anIdentifier copy]; 32 | 33 | return self; 34 | } 35 | 36 | - (void)dealloc { 37 | [identifier release]; 38 | [super dealloc]; 39 | } 40 | 41 | - (void)awakeFromNib { 42 | identifier = nil; 43 | } 44 | 45 | - (void)prepareForReuse { 46 | self.selected = NO; 47 | self.highlighted = NO; 48 | } 49 | 50 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 51 | self.highlighted = YES; 52 | [super touchesEnded:touches withEvent:event]; 53 | } 54 | 55 | - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { 56 | self.highlighted = NO; 57 | [super touchesCancelled:touches withEvent:event]; 58 | } 59 | 60 | - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 61 | self.highlighted = NO; 62 | [[self gridView] selectRow:self.yPosition column:self.xPosition scrollPosition:DTGridViewScrollPositionNone animated:YES]; 63 | [self.delegate gridViewCellWasTouched:self]; 64 | [super touchesEnded:touches withEvent:event]; 65 | } 66 | 67 | #pragma mark - 68 | #pragma mark Private Methods 69 | 70 | - (DTGridView *)gridView { 71 | UIResponder *r = [self nextResponder]; 72 | if (![r isKindOfClass:[DTGridView class]]) return nil; 73 | return (DTGridView *)r; 74 | } 75 | 76 | @end 77 | -------------------------------------------------------------------------------- /DTGridViewCellInfoProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // DTGridViewCellInfoProtocol.h 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 13.07.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | @protocol DTGridViewCellInfoProtocol 10 | @property (nonatomic, assign) NSUInteger xPosition, yPosition; 11 | @property (nonatomic, assign) CGRect frame; 12 | @end 13 | -------------------------------------------------------------------------------- /DTGridViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DTGridViewController.h 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 19.04.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DTGridView.h" 11 | 12 | @interface DTGridViewController : UIViewController { 13 | DTGridView *gridView; 14 | } 15 | 16 | @property (nonatomic, retain) DTGridView *gridView; 17 | 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /DTGridViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DTGridViewController.m 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 19.04.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import "DTGridViewController.h" 10 | 11 | 12 | @implementation DTGridViewController 13 | 14 | @synthesize gridView; 15 | 16 | - (void)viewDidLoad { 17 | [super viewDidLoad]; 18 | self.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; 19 | self.view.autoresizesSubviews = YES; 20 | gridView = [[DTGridView alloc] initWithFrame:self.view.bounds]; 21 | self.gridView.autoresizingMask = self.view.autoresizingMask; 22 | [self.view addSubview:self.gridView]; 23 | } 24 | 25 | - (void)viewDidUnload { 26 | self.gridView = nil; 27 | } 28 | 29 | - (void)dealloc { 30 | [gridView release]; 31 | gridView = nil; 32 | [super dealloc]; 33 | } 34 | 35 | - (NSInteger)numberOfRowsInGridView:(DTGridView *)gridView { 36 | return 0; 37 | } 38 | - (NSInteger)numberOfColumnsInGridView:(DTGridView *)gridView forRowWithIndex:(NSInteger)theIndex { 39 | return 0; 40 | } 41 | - (CGFloat)gridView:(DTGridView *)gridView heightForRow:(NSInteger)rowIndex { 42 | return 0.0f; 43 | } 44 | - (CGFloat)gridView:(DTGridView *)gridView widthForCellAtRow:(NSInteger)rowIndex column:(NSInteger)columnIndex { 45 | return 0.0f; 46 | } 47 | - (DTGridViewCell *)gridView:(DTGridView *)gridView viewForRow:(NSInteger)rowIndex column:(NSInteger)columnIndex { 48 | return nil; 49 | } 50 | @end 51 | -------------------------------------------------------------------------------- /DTInfiniteGridView/DTInfiniteGridView.h: -------------------------------------------------------------------------------- 1 | // 2 | // DTInfiniteGridView.h 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 11.08.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DTGridView.h" 11 | 12 | 13 | @interface DTInfiniteGridView : DTGridView { 14 | NSInteger fakeNumberOfRows; 15 | NSMutableDictionary *numberOfColumns; 16 | 17 | NSInteger segmentMultiplier; 18 | } 19 | 20 | @property (nonatomic, assign) BOOL infiniteVerticalScrolling, infiniteHorizontalScrolling; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /DTInfiniteGridView/DTInfiniteGridView.m: -------------------------------------------------------------------------------- 1 | // 2 | // DTInfiniteGridView.m 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 11.08.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import "DTInfiniteGridView.h" 10 | 11 | 12 | @implementation DTInfiniteGridView 13 | 14 | @synthesize infiniteVerticalScrolling, infiniteHorizontalScrolling; 15 | 16 | - (id)initWithFrame:(CGRect)frame { 17 | 18 | if (!(self = [super initWithFrame:frame])) return nil; 19 | 20 | numberOfColumns = [[NSMutableDictionary alloc] init]; 21 | self.showsHorizontalScrollIndicator = NO; 22 | self.bounces = NO; 23 | return self; 24 | } 25 | 26 | - (NSInteger)realRowNumber:(NSInteger)row { 27 | if (row >= fakeNumberOfRows) 28 | return (row % fakeNumberOfRows); 29 | 30 | return row; 31 | } 32 | 33 | - (NSInteger)realColumnNumber:(NSInteger)column inRow:(NSInteger)row { 34 | NSInteger theNumberOfColumns = [[numberOfColumns objectForKey:[NSString stringWithFormat:@"%i", row]] intValue]; 35 | 36 | if (column >= theNumberOfColumns) 37 | return (column % theNumberOfColumns); 38 | 39 | return column; 40 | } 41 | 42 | #pragma mark - 43 | #pragma mark Finding stuff from DataSource 44 | 45 | - (NSInteger)findNumberOfRows { 46 | 47 | fakeNumberOfRows = [self.dataSource numberOfRowsInGridView:self]; 48 | 49 | if (self.infiniteVerticalScrolling) 50 | fakeNumberOfRows = fakeNumberOfRows * 2; 51 | 52 | return fakeNumberOfRows; 53 | } 54 | 55 | - (NSInteger)findNumberOfColumnsForRow:(NSInteger)row { 56 | NSInteger amount = [self.dataSource numberOfColumnsInGridView:self forRowWithIndex:row]; 57 | segmentMultiplier = 10; 58 | 59 | if (!self.infiniteHorizontalScrolling) 60 | return amount; 61 | 62 | [numberOfColumns setObject:[NSNumber numberWithInt:amount] forKey:[NSString stringWithFormat:@"%i", row]]; 63 | 64 | return (amount * segmentMultiplier); 65 | 66 | 67 | } 68 | 69 | - (CGFloat)findWidthForRow:(NSInteger)row column:(NSInteger)column { 70 | 71 | if (self.infiniteVerticalScrolling || self.infiniteHorizontalScrolling) 72 | return [self.dataSource gridView:self widthForCellAtRow:[self realRowNumber:row] column:[self realColumnNumber:column inRow:row]]; 73 | 74 | return [self.dataSource gridView:self widthForCellAtRow:row column:column]; 75 | } 76 | 77 | - (CGFloat)findHeightForRow:(NSInteger)row { 78 | 79 | if (self.infiniteVerticalScrolling) 80 | return [self.dataSource gridView:self heightForRow:[self realRowNumber:row]]; 81 | 82 | return [self.dataSource gridView:self heightForRow:row]; 83 | } 84 | 85 | - (DTGridViewCell *)findViewForRow:(NSInteger)row column:(NSInteger)column { 86 | if (self.infiniteVerticalScrolling || self.infiniteHorizontalScrolling) 87 | return [self.dataSource gridView:self viewForRow:[self realRowNumber:row] column:[self realColumnNumber:column inRow:row]]; 88 | 89 | return [self.dataSource gridView:self viewForRow:row column:column]; 90 | } 91 | 92 | 93 | - (void)layoutSubviews { 94 | 95 | CGFloat newX = self.contentOffset.x; 96 | CGFloat newY = self.contentOffset.y; 97 | 98 | if (self.infiniteHorizontalScrolling) { 99 | 100 | CGFloat segmentWidth = self.contentSize.width/5; 101 | 102 | if (self.contentOffset.x < 2*segmentWidth) 103 | newX = self.contentOffset.x + segmentWidth; 104 | else if (self.contentOffset.x > 3*segmentWidth) 105 | newX = self.contentOffset.x - segmentWidth; 106 | } 107 | 108 | 109 | if (self.infiniteVerticalScrolling) { 110 | 111 | CGFloat segmentHeight = self.contentSize.height/5; 112 | 113 | if (self.contentOffset.y < 2*segmentHeight) 114 | newY = self.contentOffset.y + segmentHeight; 115 | else if (self.contentOffset.y > 3*segmentHeight) 116 | newY = self.contentOffset.y - segmentHeight; 117 | } 118 | 119 | self.contentOffset = CGPointMake(newX, newY); 120 | 121 | [super layoutSubviews]; 122 | } 123 | 124 | @end 125 | -------------------------------------------------------------------------------- /DTSnapGridView/DTLabelsSnapGridViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // DTLabelsSnapGridViewCell.h 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 07.07.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DTSnapGridView.h" 11 | 12 | @interface DTLabelsSnapGridViewCell : DTSnapGridViewCell { 13 | UILabel *titleLabel, *subtitleLabel; 14 | UIColor *selectedTextColor, *textColor; 15 | 16 | } 17 | 18 | @property (nonatomic, retain) UILabel *titleLabel, *subtitleLabel; 19 | @property (nonatomic, retain) UIColor *selectedTextColor, *textColor; 20 | @end 21 | -------------------------------------------------------------------------------- /DTSnapGridView/DTLabelsSnapGridViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // DTLabelsSnapGridViewCell.m 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 07.07.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import "DTLabelsSnapGridViewCell.h" 10 | 11 | 12 | @implementation DTLabelsSnapGridViewCell 13 | 14 | @synthesize titleLabel, subtitleLabel, selectedTextColor, textColor; 15 | 16 | - (id)initWithReuseIdentifier:(NSString *)anIdentifier { 17 | 18 | if (!(self = [super initWithReuseIdentifier:anIdentifier])) return nil; 19 | 20 | titleLabel = [[UILabel alloc] init]; 21 | subtitleLabel = [[UILabel alloc] init]; 22 | selectedTextColor = [UIColor whiteColor]; 23 | textColor = [UIColor whiteColor]; 24 | 25 | return self; 26 | } 27 | 28 | - (void)layoutSubviews { 29 | [super layoutSubviews]; 30 | 31 | if (self.slideAmount <= 0.5 || self.slideAmount > 1.5) { 32 | self.titleLabel.textColor = self.textColor; 33 | self.subtitleLabel.textColor = self.textColor; 34 | } else { 35 | self.titleLabel.textColor = self.selectedTextColor; 36 | self.subtitleLabel.textColor = self.selectedTextColor; 37 | } 38 | } 39 | 40 | - (void)prepareForReuse { 41 | self.frame = CGRectZero; 42 | } 43 | 44 | - (void)drawRect:(CGRect)rect { 45 | 46 | NSInteger halfHeight = (NSInteger)(self.frame.size.height/2.0); 47 | 48 | CGSize labelSize = [self.titleLabel.text sizeWithFont:self.titleLabel.font]; 49 | self.titleLabel.frame = CGRectMake(0.0f, halfHeight-labelSize.height, labelSize.width, labelSize.height); 50 | 51 | labelSize = [self.subtitleLabel.text sizeWithFont:self.subtitleLabel.font]; 52 | self.subtitleLabel.frame = CGRectMake(0.0f, halfHeight+1.0f, labelSize.width, labelSize.height); 53 | 54 | [self addSubview:self.titleLabel]; 55 | [self addSubview:self.subtitleLabel]; 56 | 57 | [self layoutSubviews]; 58 | } 59 | 60 | - (void)dealloc { 61 | [titleLabel release]; 62 | [subtitleLabel release]; 63 | [super dealloc]; 64 | } 65 | 66 | - (NSString *)description { 67 | return [NSString stringWithFormat:@"<%@ title:%@ frame=(%i %i; %i %i)>", [self class], self.titleLabel.text, (NSInteger)self.frame.origin.x, (NSInteger)self.frame.origin.y, (NSInteger)self.frame.size.width, (NSInteger)self.frame.size.height]; 68 | } 69 | 70 | @end 71 | -------------------------------------------------------------------------------- /DTSnapGridView/DTSnapGridView.h: -------------------------------------------------------------------------------- 1 | // 2 | // DTSnapGridView.h 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 07.07.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DTGridView.h" 11 | #import "DTSnapGridViewCell.h" 12 | 13 | @class DTSnapGridView; 14 | 15 | @protocol DTSnapGridViewDelegate 16 | - (void)snapGridView:(DTSnapGridView *)snapGridView didHighlightIndex:(NSInteger)index; 17 | @end 18 | 19 | @interface DTSnapGridView : DTGridView { 20 | DTSnapGridViewCell *selectedCell; 21 | } 22 | @property (nonatomic, assign) IBOutlet id delegate; 23 | @end 24 | -------------------------------------------------------------------------------- /DTSnapGridView/DTSnapGridView.m: -------------------------------------------------------------------------------- 1 | // 2 | // DTSnapGridView.m 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 07.07.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import "DTSnapGridView.h" 10 | 11 | @interface DTSnapGridView () 12 | @end 13 | 14 | @implementation DTSnapGridView 15 | 16 | @dynamic delegate; 17 | - (void)dealloc { 18 | [decelerationTimer release]; 19 | decelerationTimer = nil; 20 | [super dealloc]; 21 | } 22 | 23 | - (void)layoutSubviews { 24 | [super layoutSubviews]; 25 | 26 | for (UIView *aView in self.subviews) { 27 | 28 | if ([aView isKindOfClass:[DTSnapGridViewCell class]]) { 29 | 30 | DTSnapGridViewCell *v = (DTSnapGridViewCell *)aView; 31 | 32 | v.slideAmount = (2*(v.center.x-self.contentOffset.x) + 2*v.frame.size.width - self.frame.size.width)/(self.frame.size.width - v.frame.size.width); 33 | 34 | if (v.slideAmount > 0.5 && v.slideAmount <= 1.5 && ![v isEqual:selectedCell]) { 35 | selectedCell = v; 36 | } 37 | } 38 | } 39 | } 40 | 41 | 42 | - (void)didEndMoving { 43 | [self scrollViewToRow:0 column:selectedCell.xPosition scrollPosition:DTGridViewScrollPositionMiddleCenter animated:YES]; 44 | } 45 | 46 | - (CGFloat)findWidthForRow:(NSInteger)row column:(NSInteger)column { 47 | NSInteger w = (NSInteger)self.frame.size.width/3.0f; 48 | return (CGFloat)w; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /DTSnapGridView/DTSnapGridViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // DTSnapGridViewCell.h 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 07.07.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DTGridViewCell.h" 11 | 12 | @interface DTSnapGridViewCell : DTGridViewCell { 13 | 14 | CGFloat slideAmount; 15 | 16 | } 17 | 18 | @property (nonatomic, assign) CGFloat slideAmount; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /DTSnapGridView/DTSnapGridViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // DTSnapGridViewCell.m 3 | // DTKit 4 | // 5 | // Created by Daniel Tull on 07.07.2009. 6 | // Copyright 2009 Daniel Tull. All rights reserved. 7 | // 8 | 9 | #import "DTSnapGridViewCell.h" 10 | 11 | @implementation DTSnapGridViewCell 12 | 13 | @synthesize slideAmount; 14 | 15 | - (void)setSlideAmount:(CGFloat)amount { 16 | slideAmount = amount; 17 | [self setNeedsLayout]; 18 | } 19 | 20 | - (void)layoutSubviews { 21 | CGFloat v = self.slideAmount; 22 | CGFloat s = self.frame.size.width; 23 | 24 | for (UIView *view in self.subviews) { 25 | CGFloat l = view.frame.size.width; 26 | NSInteger x = (NSInteger)((((v * (s - l)) + l) / 2) - l/2); 27 | view.frame = CGRectMake((CGFloat)x, view.frame.origin.y, l, view.frame.size.height); 28 | } 29 | } 30 | 31 | - (void)drawRect:(CGRect)rect { 32 | [super drawRect:rect]; 33 | [self setNeedsLayout]; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Readme.textile: -------------------------------------------------------------------------------- 1 | h1. DTGridView 2 | 3 | A two-dimensional scrolling view component for the iPhone, heavily inspired by UITableView. 4 | 5 | *WARNING* DTGridView 1.1 moves the location of all of the classes, so you may need to jiggle things about when updating. 6 | 7 | h2. Branch Structure 8 | 9 | There are two branches to this repository, *master* and *production*, these are described below. (Thanks to "Abizer":https://github.com/Abizern for showing me this method.) 10 | 11 | h3. The master Branch 12 | 13 | The master branch contains the class extension files as well as an Xcode project that demonstrates the code and is the branch to use to see how to use the code. It as also the branch that further development of the code should be performed on. 14 | 15 | h3. The production Branch 16 | 17 | The production branch should be used if you want to add these extensions as a git submodule in other projects and will only contain the class files themselves without the Xcode project or example classes. This is preferable as it will keep your directories clean of any code which is unnecessary to your working project, of course you can switch branches in the submodule to access the given samples. 18 | 19 | Changes made to the master branch will be merged across to production, so it will always remain current with respect to master. 20 | 21 | To add the production branch rather than master, simply use the -b flag as shown below. 22 | 23 | bc. git submodule add -b production git://github.com/danielctull/DTGridView.git 24 | 25 | To keep up to date with the latest changes `cd` into the directory that contains this submodule and pull the newest changes as usual 26 | 27 | bc. git pull origin 28 | 29 | h3. Artefacts 30 | 31 | Sometimes, there may be artefacts left over when switching from master to production. These are files that are ignored by git and are easily cleaned up by running 32 | 33 | bc. git clean -dxf 34 | 35 | h2. Examples 36 | 37 | Examples of some of these features can be found in the iPhone app delegate. 38 | 39 | h2. License 40 | 41 | Copyright (C) 2010 Daniel Tull. All rights reserved. 42 | 43 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 44 | 45 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 46 | 47 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 48 | 49 | * Neither the name of the author nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 50 | 51 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --------------------------------------------------------------------------------