├── .gitignore ├── Chapter01 ├── .DS_Store └── SimpleTable │ ├── .DS_Store │ ├── License.txt │ ├── SimpleTable.xcodeproj │ └── project.pbxproj │ └── SimpleTable │ ├── .DS_Store │ ├── STAppDelegate.h │ ├── STAppDelegate.m │ ├── STViewController.h │ ├── STViewController.m │ ├── SimpleTable-Info.plist │ ├── SimpleTable-Prefix.pch │ ├── en.lproj │ ├── InfoPlist.strings │ └── STViewController.xib │ └── main.m ├── Chapter05 ├── .DS_Store └── BabyNames │ ├── .DS_Store │ ├── BabyNames.xcodeproj │ └── project.pbxproj │ ├── BabyNames │ ├── BNAppDelegate.h │ ├── BNAppDelegate.m │ ├── BNDetailViewController.h │ ├── BNDetailViewController.m │ ├── BNDetailViewController.xib │ ├── BNName.h │ ├── BNName.m │ ├── BNViewController.h │ ├── BNViewController.m │ ├── BabyNames-Info.plist │ ├── BabyNames-Prefix.pch │ ├── en.lproj │ │ ├── BNViewController.xib │ │ └── InfoPlist.strings │ ├── icon1.png │ ├── icon2.png │ ├── icon3.png │ ├── icon4.png │ ├── icon5.png │ └── main.m │ └── License.txt ├── Chapter06 ├── .DS_Store ├── NamesApp │ ├── .DS_Store │ ├── NamesApp.xcodeproj │ │ └── project.pbxproj │ └── NamesApp │ │ ├── .DS_Store │ │ ├── License.txt │ │ ├── NAAppDelegate.h │ │ ├── NAAppDelegate.m │ │ ├── NAViewController.h │ │ ├── NAViewController.m │ │ ├── Names.plist │ │ ├── NamesApp-Info.plist │ │ ├── NamesApp-Prefix.pch │ │ ├── en.lproj │ │ ├── InfoPlist.strings │ │ └── NAViewController.xib │ │ └── main.m └── SimpleIndexedTable │ ├── .DS_Store │ ├── SimpleIndexedTable.xcodeproj │ └── project.pbxproj │ └── SimpleIndexedTable │ ├── CMAppDelegate.h │ ├── CMAppDelegate.m │ ├── CMViewController.h │ ├── CMViewController.m │ ├── License.txt │ ├── SimpleIndexedTable-Info.plist │ ├── SimpleIndexedTable-Prefix.pch │ ├── en.lproj │ ├── CMViewController.xib │ └── InfoPlist.strings │ └── main.m ├── Chapter07 ├── .DS_Store └── EditingApp │ ├── .DS_Store │ ├── EditingApp.xcodeproj │ └── project.pbxproj │ ├── EditingApp │ ├── CMAppDelegate.h │ ├── CMAppDelegate.m │ ├── CMViewController.h │ ├── CMViewController.m │ ├── EditingApp-Info.plist │ ├── EditingApp-Prefix.pch │ ├── en.lproj │ │ ├── CMViewController.xib │ │ └── InfoPlist.strings │ └── main.m │ └── License.txt ├── Chapter08 └── CellsFromNibs │ ├── CellsFromNibs.xcodeproj │ └── project.pbxproj │ ├── CellsFromNibs │ ├── CMAppDelegate.h │ ├── CMAppDelegate.m │ ├── CMViewController.h │ ├── CMViewController.m │ ├── CMViewController.xib │ ├── CellsFromNibs-Info.plist │ ├── CellsFromNibs-Prefix.pch │ ├── NewCell.xib │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m │ └── License.txt ├── Chapter09 └── CodeCustomCells │ ├── CodeCustomCells.xcodeproj │ └── project.pbxproj │ ├── License.txt │ └── MultiCustomCells │ ├── CodeCustomCells-Info.plist │ ├── CodeCustomCells-Prefix.pch │ ├── EvenCell.h │ ├── EvenCell.m │ ├── EvenCell.xib │ ├── OddCell.h │ ├── OddCell.m │ ├── OddCell.xib │ ├── TVAppDelegate.h │ ├── TVAppDelegate.m │ ├── TVTableController.h │ ├── TVTableController.m │ ├── TVTableController.xib │ ├── bluePrint.png │ ├── corkboard.png │ ├── en.lproj │ └── InfoPlist.strings │ ├── gingham.png │ ├── main.m │ ├── planet.png │ └── star.png ├── Chapter10 ├── .DS_Store ├── SimpleCellControls │ ├── .DS_Store │ ├── SCCTableController.h │ ├── SCCTableController.m │ ├── SCCTableController.xib │ ├── SimpleCellControls.xcodeproj │ │ └── project.pbxproj │ └── SimpleCellControls │ │ ├── CustomCell.h │ │ ├── CustomCell.m │ │ ├── License.txt │ │ ├── SCCAppDelegate.h │ │ ├── SCCAppDelegate.m │ │ ├── SimpleCellControls-Info.plist │ │ ├── SimpleCellControls-Prefix.pch │ │ ├── en.lproj │ │ └── InfoPlist.strings │ │ └── main.m ├── SimpleTaps │ ├── .DS_Store │ ├── License.txt │ ├── SimpleTaps.xcodeproj │ │ └── project.pbxproj │ └── SimpleTaps │ │ ├── CMAppDelegate.h │ │ ├── CMAppDelegate.m │ │ ├── CMViewController.h │ │ ├── CMViewController.m │ │ ├── SimpleTaps-Info.plist │ │ ├── SimpleTaps-Prefix.pch │ │ ├── en.lproj │ │ ├── CMViewController.xib │ │ └── InfoPlist.strings │ │ └── main.m └── SwipeAndPullRefreshTable │ ├── .DS_Store │ ├── SwipeAndPullRefreshTable.xcodeproj │ └── project.pbxproj │ └── SwipingTable │ ├── License.txt │ ├── SwipeAndPullRefreshTable-Info.plist │ ├── SwipeAndPullRefreshTable-Prefix.pch │ ├── SwipeAndPullRefreshTableAppDelegate.h │ ├── SwipeAndPullRefreshTableAppDelegate.m │ ├── SwipeCell.h │ ├── SwipeCell.m │ ├── SwipeCellProtocol.h │ ├── SwipeTableController.h │ ├── SwipeTableController.m │ ├── SwipeTableController.xib │ ├── en.lproj │ └── InfoPlist.strings │ ├── main.m │ └── point.png ├── Chapter11 ├── .DS_Store └── SplitViewApp │ ├── .DS_Store │ ├── SplitViewApp.xcodeproj │ └── project.pbxproj │ └── SplitViewApp │ ├── LeftTableViewController.h │ ├── LeftTableViewController.m │ ├── LeftTableViewController.xib │ ├── License.txt │ ├── RightDetailViewController.h │ ├── RightDetailViewController.m │ ├── RightDetailViewController.xib │ ├── SVAppDelegate.h │ ├── SVAppDelegate.m │ ├── SplitViewApp-Info.plist │ ├── SplitViewApp-Prefix.pch │ ├── UpdateSplitDetailViewProtocol.h │ ├── en.lproj │ └── InfoPlist.strings │ └── main.m └── Readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Exclude the build directory 2 | build/* 3 | 4 | # Exclude temp nibs and swap files 5 | *~.nib 6 | *.swp 7 | 8 | # Exclude OS X folder attributes 9 | .DS_Store 10 | 11 | # Exclude user-specific XCode 3 and 4 files 12 | *.mode1 13 | *.mode1v3 14 | *.mode2v3 15 | *.perspective 16 | *.perspectivev3 17 | *.pbxuser 18 | *.xcworkspace 19 | xcuserdata -------------------------------------------------------------------------------- /Chapter01/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter01/.DS_Store -------------------------------------------------------------------------------- /Chapter01/SimpleTable/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter01/SimpleTable/.DS_Store -------------------------------------------------------------------------------- /Chapter01/SimpleTable/License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Chapter01/SimpleTable/SimpleTable/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter01/SimpleTable/SimpleTable/.DS_Store -------------------------------------------------------------------------------- /Chapter01/SimpleTable/SimpleTable/STAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // STAppDelegate.h 3 | // SimpleTable 4 | // 5 | // Created by TimD on 05/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. Some rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class STViewController; 12 | 13 | @interface STAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) STViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Chapter01/SimpleTable/SimpleTable/STAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // STAppDelegate.m 3 | // SimpleTable 4 | // 5 | // Created by TimD on 05/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. Some rights reserved. 7 | // 8 | 9 | #import "STAppDelegate.h" 10 | 11 | #import "STViewController.h" 12 | 13 | @implementation STAppDelegate 14 | 15 | @synthesize window = _window; 16 | @synthesize viewController = _viewController; 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 19 | { 20 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 21 | // Override point for customization after application launch. 22 | self.viewController = [[STViewController alloc] initWithNibName:@"STViewController" bundle:nil]; 23 | self.window.rootViewController = self.viewController; 24 | [self.window makeKeyAndVisible]; 25 | return YES; 26 | } 27 | 28 | - (void)applicationWillResignActive:(UIApplication *)application 29 | { 30 | /* 31 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 32 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 33 | */ 34 | } 35 | 36 | - (void)applicationDidEnterBackground:(UIApplication *)application 37 | { 38 | /* 39 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 40 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 41 | */ 42 | } 43 | 44 | - (void)applicationWillEnterForeground:(UIApplication *)application 45 | { 46 | /* 47 | Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 48 | */ 49 | } 50 | 51 | - (void)applicationDidBecomeActive:(UIApplication *)application 52 | { 53 | /* 54 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 55 | */ 56 | } 57 | 58 | - (void)applicationWillTerminate:(UIApplication *)application 59 | { 60 | /* 61 | Called when the application is about to terminate. 62 | Save data if appropriate. 63 | See also applicationDidEnterBackground:. 64 | */ 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Chapter01/SimpleTable/SimpleTable/STViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // STViewController.h 3 | // SimpleTable 4 | // 5 | // Created by TimD on 05/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. Some rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface STViewController : UIViewController 12 | 13 | @property (nonatomic, strong) NSMutableArray *tableData; // holds the table data 14 | @property (nonatomic) int cellCount; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Chapter01/SimpleTable/SimpleTable/STViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // STViewController.m 3 | // SimpleTable 4 | // 5 | // Created by TimD on 05/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. Some rights reserved. 7 | // 8 | 9 | #import "STViewController.h" 10 | 11 | @implementation STViewController 12 | 13 | @synthesize tableData; 14 | @synthesize cellCount; 15 | 16 | - (void)didReceiveMemoryWarning 17 | { 18 | [super didReceiveMemoryWarning]; 19 | // Release any cached data, images, etc that aren't in use. 20 | } 21 | 22 | #pragma mark - UITableViewDataSource 23 | 24 | -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 25 | return 1; 26 | } 27 | 28 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 29 | return [self.tableData count]; 30 | } 31 | 32 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 33 | 34 | static NSString *cellIdentifier = @"Cell"; 35 | 36 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 37 | 38 | if (cell == nil) { 39 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; 40 | } 41 | 42 | cell.textLabel.text = [self.tableData objectAtIndex:indexPath.row]; 43 | 44 | return cell; 45 | 46 | } 47 | 48 | #pragma mark - UITableViewDelegate 49 | 50 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 51 | 52 | NSLog(@"Table row %d has been tapped", indexPath.row); 53 | 54 | NSString *messageString = [NSString stringWithFormat:@"You tapped row %d", indexPath.row]; 55 | 56 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Row tapped" message:messageString delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; 57 | 58 | [alert show]; 59 | 60 | } 61 | 62 | #pragma mark - View lifecycle 63 | 64 | - (void)viewDidLoad 65 | { 66 | [super viewDidLoad]; 67 | // Do any additional setup after loading the view, typically from a nib. 68 | 69 | // Create the array to hold the table data 70 | self.tableData = [[NSMutableArray alloc] init]; 71 | 72 | // Create and add 10 data items to the table data array 73 | for (NSUInteger i=0; i<10; i++) { 74 | 75 | // The cell will contain a string "Item X" 76 | NSString *dataString = [NSString stringWithFormat:@"Item %d", i]; 77 | 78 | // Here the new string is added to the end of the array 79 | [self.tableData addObject:dataString]; 80 | 81 | } 82 | 83 | // Print out the contents of the array into the log 84 | NSLog(@"The tableData array contains %@", self.tableData); 85 | 86 | } 87 | 88 | - (void)viewDidUnload 89 | { 90 | [super viewDidUnload]; 91 | // Release any retained subviews of the main view. 92 | // e.g. self.myOutlet = nil; 93 | self.tableData = nil; 94 | self.cellCount = nil; 95 | } 96 | 97 | - (void)viewWillAppear:(BOOL)animated 98 | { 99 | [super viewWillAppear:animated]; 100 | } 101 | 102 | - (void)viewDidAppear:(BOOL)animated 103 | { 104 | [super viewDidAppear:animated]; 105 | } 106 | 107 | - (void)viewWillDisappear:(BOOL)animated 108 | { 109 | [super viewWillDisappear:animated]; 110 | } 111 | 112 | - (void)viewDidDisappear:(BOOL)animated 113 | { 114 | [super viewDidDisappear:animated]; 115 | } 116 | 117 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 118 | { 119 | // Return YES for supported orientations 120 | return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 121 | } 122 | 123 | @end 124 | -------------------------------------------------------------------------------- /Chapter01/SimpleTable/SimpleTable/SimpleTable-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFiles 12 | 13 | CFBundleIdentifier 14 | uk.co.charismaticmegafauna.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Chapter01/SimpleTable/SimpleTable/SimpleTable-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SimpleTable' target in the 'SimpleTable' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Chapter01/SimpleTable/SimpleTable/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Chapter01/SimpleTable/SimpleTable/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SimpleTable 4 | // 5 | // Created by TimD on 05/02/2012. 6 | // Copyright (c) 2012 __MyCompanyName__. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "STAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([STAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter05/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter05/.DS_Store -------------------------------------------------------------------------------- /Chapter05/BabyNames/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter05/BabyNames/.DS_Store -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/BNAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // BNAppDelegate.h 3 | // BabyNames 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 7 | // See license.txt for licensing information. 8 | // 9 | 10 | #import 11 | 12 | @class BNViewController; 13 | 14 | @interface BNAppDelegate : UIResponder 15 | 16 | @property (strong, nonatomic) UIWindow *window; 17 | 18 | @property (strong, nonatomic) BNViewController *viewController; 19 | 20 | @property (nonatomic, strong) NSMutableArray *tableData; 21 | 22 | 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/BNAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // BNAppDelegate.m 3 | // BabyNames 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 7 | // See license.txt for licensing information. 8 | // 9 | 10 | #import "BNAppDelegate.h" 11 | 12 | #import "BNViewController.h" 13 | 14 | #import "BNName.h" 15 | 16 | @interface BNAppDelegate() 17 | 18 | -(BNName *)createNameWithNonsenseDataWithIndex:(int)index; 19 | 20 | @end 21 | 22 | @implementation BNAppDelegate 23 | 24 | @synthesize window = _window; 25 | @synthesize viewController = _viewController; 26 | 27 | @synthesize tableData; 28 | 29 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 30 | { 31 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 32 | 33 | // Create dummy data 34 | 35 | NSUInteger numberOfNames = 25; 36 | 37 | self.tableData = [[NSMutableArray alloc] initWithCapacity:numberOfNames]; 38 | 39 | // Create a temporary array of tableData 40 | for (NSUInteger i = 0; i < numberOfNames; i++) { 41 | 42 | // Create a new name with nonsense data 43 | BNName *tempName = [self createNameWithNonsenseDataWithIndex:i]; 44 | 45 | // Add it to the temporary array 46 | [self.tableData addObject:tempName]; 47 | 48 | } 49 | 50 | // Create an instance of BNViewController 51 | BNViewController *bnViewController = [[BNViewController alloc] initWithNibName:@"BNViewController" bundle:nil]; 52 | 53 | // Pass the array of dummy names into the view controller 54 | bnViewController.tableData = (NSArray *)self.tableData; 55 | 56 | // Create an instance of UINavigationController called navController 57 | // and set the bnViewController as its RootViewController 58 | UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:bnViewController]; 59 | 60 | // Make the navController the rootViewController 61 | self.window.rootViewController = navController; 62 | 63 | [self.window makeKeyAndVisible]; 64 | return YES; 65 | } 66 | 67 | - (void)applicationWillResignActive:(UIApplication *)application 68 | { 69 | /* 70 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 71 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 72 | */ 73 | } 74 | 75 | - (void)applicationDidEnterBackground:(UIApplication *)application 76 | { 77 | /* 78 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 79 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 80 | */ 81 | } 82 | 83 | - (void)applicationWillEnterForeground:(UIApplication *)application 84 | { 85 | /* 86 | Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 87 | */ 88 | } 89 | 90 | - (void)applicationDidBecomeActive:(UIApplication *)application 91 | { 92 | /* 93 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 94 | */ 95 | } 96 | 97 | - (void)applicationWillTerminate:(UIApplication *)application 98 | { 99 | /* 100 | Called when the application is about to terminate. 101 | Save data if appropriate. 102 | See also applicationDidEnterBackground:. 103 | */ 104 | } 105 | 106 | -(BNName *)createNameWithNonsenseDataWithIndex:(int)index { 107 | 108 | BNName *randomDataName = [[BNName alloc] init]; 109 | 110 | NSArray *namesArray = [[NSArray alloc] initWithObjects:@"Abigail", @"Ada", @"Adelaide", @"Abel", @"Algernon", @"Anatole", @"Barbara", @"Bertha", @"Brunhilda",@"Barton", @"Ben", @"Boris", @"Calista", @"Cassandra", @"Constance", @"Caspar", @"Clive", @"Corey", @"Danica", @"Dido", @"Dora", @"Darnell", @"Dexter", @"Dunstan", @"Duncan", nil]; 111 | 112 | NSArray *genderArray = [[NSArray alloc] initWithObjects:@"Boy", @"Girl", @"Unisex", nil]; 113 | 114 | NSArray *notesArray = [[NSArray alloc] initWithObjects:@"'Prosperous and joyful'. A popular name in Victorian times.", @"'Bright fair one'. A term of endearment used by the Irish", @"'Son of the furrows; ploughman' One of the twelve apostles", @"One who is graceful and charming", @"'Spear'. A warrior who wielded her spear to the detriment of her enemies", nil]; 115 | 116 | NSArray *derivationArray = [[NSArray alloc] initWithObjects:@"Celtic", @"Germanic", @"Old English", @"Latin", @"Greek", nil]; 117 | 118 | NSArray *iconArray = [[NSArray alloc] initWithObjects:@"icon1.png", @"icon2.png", @"icon3.png", @"icon4.png", @"icon5.png", nil]; 119 | 120 | int genderCount = [genderArray count]; 121 | int notesCount = [notesArray count]; 122 | int derivationCount = [derivationArray count]; 123 | int iconCount = [iconArray count]; 124 | 125 | randomDataName.nameText = [namesArray objectAtIndex:index]; 126 | randomDataName.gender = [genderArray objectAtIndex:(arc4random() % genderCount)]; 127 | randomDataName.derivation = [derivationArray objectAtIndex:(arc4random() % derivationCount)]; 128 | randomDataName.iconName = [iconArray objectAtIndex:(arc4random() % iconCount)]; 129 | randomDataName.notes = [notesArray objectAtIndex:(arc4random() % notesCount)]; 130 | 131 | return randomDataName; 132 | } 133 | 134 | @end 135 | -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/BNDetailViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BNDetailViewController.h 3 | // BabyNames 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 7 | // See license.txt for licensing information. 8 | // 9 | 10 | #import 11 | 12 | @class BNName; 13 | 14 | @interface BNDetailViewController : UIViewController 15 | 16 | @property (nonatomic, strong) BNName *BNName; 17 | @property (nonatomic, strong) IBOutlet UILabel *nameTextLabel; 18 | @property (nonatomic, strong) IBOutlet UILabel *genderLabel; 19 | @property (nonatomic, strong) IBOutlet UILabel *derivationLabel; 20 | @property (nonatomic, strong) IBOutlet UILabel *notesLabel; 21 | @property (nonatomic, strong) IBOutlet UIImageView *iconImageView; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/BNDetailViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BNDetailViewController.m 3 | // BabyNames 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 7 | // See license.txt for licensing information. 8 | // 9 | 10 | #import "BNDetailViewController.h" 11 | #import "BNName.h" 12 | 13 | @implementation BNDetailViewController 14 | 15 | @synthesize BNName; 16 | @synthesize nameTextLabel; 17 | @synthesize genderLabel; 18 | @synthesize derivationLabel; 19 | @synthesize notesLabel; 20 | @synthesize iconImageView; 21 | 22 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 23 | { 24 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 25 | if (self) { 26 | // Custom initialization 27 | } 28 | return self; 29 | } 30 | 31 | - (void)didReceiveMemoryWarning 32 | { 33 | // Releases the view if it doesn't have a superview. 34 | [super didReceiveMemoryWarning]; 35 | 36 | // Release any cached data, images, etc that aren't in use. 37 | } 38 | 39 | #pragma mark - View lifecycle 40 | 41 | - (void)viewDidLoad 42 | { 43 | [super viewDidLoad]; 44 | // Do any additional setup after loading the view from its nib. 45 | 46 | self.nameTextLabel.text = self.BNName.nameText; 47 | self.genderLabel.text = self.BNName.gender; 48 | self.derivationLabel.text = self.BNName.derivation; 49 | self.notesLabel.text = self.BNName.notes; 50 | 51 | self.iconImageView.image = [UIImage imageNamed:self.BNName.iconName]; 52 | 53 | } 54 | 55 | - (void)viewDidUnload 56 | { 57 | [super viewDidUnload]; 58 | // Release any retained subviews of the main view. 59 | // e.g. self.myOutlet = nil; 60 | self.BNName = nil; 61 | self.nameTextLabel = nil; 62 | self.genderLabel = nil; 63 | self.derivationLabel = nil; 64 | self.notesLabel = nil; 65 | self.iconImageView = nil; 66 | } 67 | 68 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 69 | { 70 | // Return YES for supported orientations 71 | return (interfaceOrientation == UIInterfaceOrientationPortrait); 72 | } 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/BNName.h: -------------------------------------------------------------------------------- 1 | // 2 | // BNName.h 3 | // BabyNames 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 7 | // See license.txt for licensing information. 8 | // 9 | 10 | #import 11 | 12 | @interface BNName : NSObject 13 | 14 | @property (nonatomic, strong) NSString *nameText; 15 | @property (nonatomic, strong) NSString *gender; 16 | @property (nonatomic, strong) NSString *derivation; 17 | @property (nonatomic, strong) NSString *iconName; 18 | @property (nonatomic, strong) NSString *notes; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/BNName.m: -------------------------------------------------------------------------------- 1 | // 2 | // BNName.m 3 | // BabyNames 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 7 | // See license.txt for licensing information. 8 | // 9 | 10 | #import "BNName.h" 11 | 12 | @implementation BNName 13 | 14 | @synthesize nameText; 15 | @synthesize gender; 16 | @synthesize derivation; 17 | @synthesize iconName; 18 | @synthesize notes; 19 | 20 | -(id)init { 21 | 22 | self = [super init]; 23 | 24 | if (self) { 25 | // initialization code 26 | } 27 | 28 | return self; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/BNViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BNViewController.h 3 | // BabyNames 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 7 | // See license.txt for licensing information. 8 | // 9 | 10 | #import 11 | 12 | @interface BNViewController : UIViewController 13 | 14 | @property (nonatomic, strong) NSArray *tableData; 15 | 16 | @property (strong, nonatomic) IBOutlet UITableView *theTableView; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/BNViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BNViewController.m 3 | // BabyNames 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 7 | // See license.txt for licensing information. 8 | // 9 | 10 | #import "BNViewController.h" 11 | #import "BNName.h" 12 | 13 | #import "BNDetailViewController.h" 14 | 15 | @implementation BNViewController 16 | 17 | @synthesize tableData; 18 | @synthesize theTableView; 19 | 20 | - (void)didReceiveMemoryWarning 21 | { 22 | [super didReceiveMemoryWarning]; 23 | // Release any cached data, images, etc that aren't in use. 24 | } 25 | 26 | #pragma mark - Table View methods 27 | 28 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 29 | 30 | if (self.tableData != nil) { 31 | return [self.tableData count]; 32 | } 33 | 34 | return 0; 35 | 36 | } 37 | 38 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 39 | 40 | static NSString *cellIdentifier = @"BabyNameCell"; 41 | 42 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 43 | 44 | if (cell == nil) { 45 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; 46 | } 47 | 48 | // Extract the BNName object from the tableData 49 | BNName *tempName = [self.tableData objectAtIndex:indexPath.row]; 50 | 51 | // Update the cell's textLabel 52 | cell.textLabel.text = tempName.nameText; 53 | 54 | return cell; 55 | 56 | } 57 | 58 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 59 | 60 | BNDetailViewController *detailViewController = [[BNDetailViewController alloc] initWithNibName:@"BNDetailViewController" bundle:nil]; 61 | 62 | detailViewController.BNName = [self.tableData objectAtIndex:indexPath.row]; 63 | 64 | [self.navigationController pushViewController:detailViewController animated:YES]; 65 | 66 | } 67 | 68 | #pragma mark - View lifecycle 69 | 70 | - (void)viewDidLoad 71 | { 72 | [super viewDidLoad]; 73 | // Do any additional setup after loading the view, typically from a nib. 74 | 75 | self.title = @"Baby Names"; 76 | 77 | } 78 | 79 | - (void)viewDidUnload 80 | { 81 | [self setTheTableView:nil]; 82 | [super viewDidUnload]; 83 | // Release any retained subviews of the main view. 84 | // e.g. self.myOutlet = nil; 85 | self.tableData = nil; 86 | self.theTableView = nil; 87 | } 88 | 89 | - (void)viewWillAppear:(BOOL)animated 90 | { 91 | [super viewWillAppear:animated]; 92 | } 93 | 94 | - (void)viewDidAppear:(BOOL)animated 95 | { 96 | [super viewDidAppear:animated]; 97 | 98 | NSIndexPath *selectedIndexPath = [self.theTableView indexPathForSelectedRow]; 99 | 100 | [self.theTableView deselectRowAtIndexPath:selectedIndexPath animated:YES]; 101 | 102 | } 103 | 104 | - (void)viewWillDisappear:(BOOL)animated 105 | { 106 | [super viewWillDisappear:animated]; 107 | } 108 | 109 | - (void)viewDidDisappear:(BOOL)animated 110 | { 111 | [super viewDidDisappear:animated]; 112 | } 113 | 114 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 115 | { 116 | // Return YES for supported orientations 117 | return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 118 | } 119 | 120 | @end 121 | -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/BabyNames-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFiles 12 | 13 | CFBundleIdentifier 14 | uk.co.charismaticmegafauna.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/BabyNames-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'BabyNames' target in the 'BabyNames' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/icon1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter05/BabyNames/BabyNames/icon1.png -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/icon2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter05/BabyNames/BabyNames/icon2.png -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/icon3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter05/BabyNames/BabyNames/icon3.png -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/icon4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter05/BabyNames/BabyNames/icon4.png -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/icon5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter05/BabyNames/BabyNames/icon5.png -------------------------------------------------------------------------------- /Chapter05/BabyNames/BabyNames/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // BabyNames 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 7 | // See license.txt for licensing information. 8 | // 9 | 10 | #import 11 | 12 | #import "BNAppDelegate.h" 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | @autoreleasepool { 17 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([BNAppDelegate class])); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chapter05/BabyNames/License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Chapter06/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter06/.DS_Store -------------------------------------------------------------------------------- /Chapter06/NamesApp/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter06/NamesApp/.DS_Store -------------------------------------------------------------------------------- /Chapter06/NamesApp/NamesApp/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter06/NamesApp/NamesApp/.DS_Store -------------------------------------------------------------------------------- /Chapter06/NamesApp/NamesApp/License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Chapter06/NamesApp/NamesApp/NAAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // NAAppDelegate.h 3 | // NamesApp 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. 7 | // See license.txt for licensing information. 8 | 9 | #import 10 | 11 | @class NAViewController; 12 | 13 | @interface NAAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) NAViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Chapter06/NamesApp/NamesApp/NAAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // NAAppDelegate.m 3 | // NamesApp 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. 7 | // See license.txt for licensing information. 8 | 9 | #import "NAAppDelegate.h" 10 | 11 | #import "NAViewController.h" 12 | 13 | @implementation NAAppDelegate 14 | 15 | @synthesize window = _window; 16 | @synthesize viewController = _viewController; 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 19 | { 20 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 21 | // Override point for customization after application launch. 22 | self.viewController = [[NAViewController alloc] initWithNibName:@"NAViewController" bundle:nil]; 23 | self.window.rootViewController = self.viewController; 24 | [self.window makeKeyAndVisible]; 25 | return YES; 26 | } 27 | 28 | - (void)applicationWillResignActive:(UIApplication *)application 29 | { 30 | /* 31 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 32 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 33 | */ 34 | } 35 | 36 | - (void)applicationDidEnterBackground:(UIApplication *)application 37 | { 38 | /* 39 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 40 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 41 | */ 42 | } 43 | 44 | - (void)applicationWillEnterForeground:(UIApplication *)application 45 | { 46 | /* 47 | Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 48 | */ 49 | } 50 | 51 | - (void)applicationDidBecomeActive:(UIApplication *)application 52 | { 53 | /* 54 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 55 | */ 56 | } 57 | 58 | - (void)applicationWillTerminate:(UIApplication *)application 59 | { 60 | /* 61 | Called when the application is about to terminate. 62 | Save data if appropriate. 63 | See also applicationDidEnterBackground:. 64 | */ 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Chapter06/NamesApp/NamesApp/NAViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // NAViewController.h 3 | // NamesApp 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. 7 | // See license.txt for licensing information. 8 | 9 | #import 10 | 11 | @interface NAViewController : UIViewController 12 | 13 | @property (nonatomic, strong) NSArray *tableData; 14 | @property (nonatomic, strong) UILocalizedIndexedCollation *collation; 15 | @property (nonatomic, strong) NSMutableArray *outerArray; 16 | @property (nonatomic, strong) NSArray *indexTitlesArray; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Chapter06/NamesApp/NamesApp/NAViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // NAViewController.m 3 | // NamesApp 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. 7 | // See license.txt for licensing information. 8 | 9 | #import "NAViewController.h" 10 | 11 | @interface NAViewController() 12 | 13 | -(void)configureSectionData; 14 | 15 | @end 16 | 17 | @implementation NAViewController 18 | 19 | @synthesize tableData; 20 | @synthesize collation; 21 | @synthesize outerArray; 22 | @synthesize indexTitlesArray; 23 | 24 | - (void)didReceiveMemoryWarning 25 | { 26 | [super didReceiveMemoryWarning]; 27 | // Release any cached data, images, etc that aren't in use. 28 | } 29 | 30 | #pragma mark - Table view methods 31 | 32 | -(void)configureSectionData { 33 | 34 | NSUInteger sectionTitlesCount = [collation.sectionTitles count]; 35 | 36 | self.outerArray = [NSMutableArray arrayWithCapacity:sectionTitlesCount]; 37 | 38 | for (NSUInteger index = 0; index < sectionTitlesCount; index++) { 39 | 40 | NSMutableArray *array = [NSMutableArray array]; 41 | 42 | [self.outerArray addObject:array]; 43 | 44 | } 45 | 46 | for (NSString *nameString in tableData) { 47 | 48 | NSInteger sectionNumber = [collation sectionForObject:nameString collationStringSelector:@selector(lowercaseString)]; 49 | 50 | NSMutableArray *sectionNames = [outerArray objectAtIndex:sectionNumber]; 51 | 52 | [sectionNames addObject:nameString]; 53 | 54 | } 55 | 56 | for (NSUInteger index = 0; index < sectionTitlesCount; index++) { 57 | 58 | NSMutableArray *namesForSection = [outerArray objectAtIndex:index]; 59 | 60 | NSArray *sortedNamesForSection = [collation sortedArrayFromArray:namesForSection collationStringSelector:@selector(lowercaseString)]; 61 | 62 | [self.outerArray replaceObjectAtIndex:index withObject:sortedNamesForSection]; 63 | 64 | } 65 | 66 | } 67 | 68 | -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 69 | return [self.collation.sectionTitles count]; 70 | } 71 | 72 | -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 73 | 74 | NSString *theLetter = [self.collation.sectionTitles objectAtIndex:section]; 75 | 76 | if (![theLetter isEqualToString:@"#"]) { 77 | NSString *titleString = [NSString stringWithFormat:@"Names for the letter %@", theLetter]; 78 | return titleString; 79 | } 80 | 81 | return nil; 82 | } 83 | 84 | -(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { 85 | return self.collation.sectionTitles; 86 | } 87 | 88 | -(NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { 89 | return [self.collation sectionForSectionIndexTitleAtIndex:index]; 90 | } 91 | 92 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 93 | 94 | NSArray *innerArray = [self.outerArray objectAtIndex:section]; 95 | return [innerArray count]; 96 | 97 | } 98 | 99 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 100 | 101 | static NSString *cellIdentifier = @"cellIdentifier"; 102 | 103 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 104 | 105 | if (!cell) { 106 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; 107 | } 108 | 109 | // Get the inner array for this section 110 | NSArray *innerArray = [self.outerArray objectAtIndex:indexPath.section]; 111 | 112 | // Get the name from the inner array 113 | NSString *theName = [innerArray objectAtIndex:indexPath.row]; 114 | 115 | cell.textLabel.text = theName; 116 | 117 | return cell; 118 | 119 | } 120 | 121 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 122 | 123 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 124 | 125 | } 126 | 127 | #pragma mark - View lifecycle 128 | 129 | - (void)viewDidLoad 130 | { 131 | [super viewDidLoad]; 132 | // Do any additional setup after loading the view, typically from a nib. 133 | 134 | NSBundle *bundle = [NSBundle mainBundle]; 135 | 136 | NSString *plistPath = [bundle pathForResource:@"Names" ofType:@"plist"]; 137 | 138 | NSDictionary *namesDictionary = [[NSDictionary alloc] initWithContentsOfFile:plistPath]; 139 | 140 | self.tableData = [namesDictionary objectForKey:@"names"]; 141 | 142 | self.collation = [UILocalizedIndexedCollation currentCollation]; 143 | 144 | [self configureSectionData]; 145 | 146 | } 147 | 148 | - (void)viewDidUnload 149 | { 150 | [super viewDidUnload]; 151 | // Release any retained subviews of the main view. 152 | // e.g. self.myOutlet = nil; 153 | 154 | self.tableData = nil; 155 | self.collation = nil; 156 | self.outerArray = nil; 157 | self.indexTitlesArray = nil; 158 | } 159 | 160 | - (void)viewWillAppear:(BOOL)animated 161 | { 162 | [super viewWillAppear:animated]; 163 | } 164 | 165 | - (void)viewDidAppear:(BOOL)animated 166 | { 167 | [super viewDidAppear:animated]; 168 | } 169 | 170 | - (void)viewWillDisappear:(BOOL)animated 171 | { 172 | [super viewWillDisappear:animated]; 173 | } 174 | 175 | - (void)viewDidDisappear:(BOOL)animated 176 | { 177 | [super viewDidDisappear:animated]; 178 | } 179 | 180 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 181 | { 182 | // Return YES for supported orientations 183 | return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 184 | } 185 | 186 | @end 187 | -------------------------------------------------------------------------------- /Chapter06/NamesApp/NamesApp/Names.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | names 6 | 7 | Aaron 8 | Aberah 9 | Aisha 10 | Cadan 11 | Cadenza 12 | Cyrene 13 | Baldric 14 | Banbha 15 | Bryony 16 | Dafyyd 17 | Dagmar 18 | Dymphna 19 | Fabian 20 | Florence 21 | Frieda 22 | Eamonn 23 | Edith 24 | Eveline 25 | Gabriella 26 | Grant 27 | Gwyneth 28 | Iago 29 | Ida 30 | Isaac 31 | Hadrian 32 | Helene 33 | Hilda 34 | Jemima 35 | Jancis 36 | Jasper 37 | Lucy 38 | Lavinia 39 | Lucas 40 | Kathleen 41 | Kenneth 42 | Kenton 43 | Maria 44 | Marion 45 | Montgomery 46 | Oscar 47 | Odette 48 | Ophelia 49 | Naomi 50 | Natalie 51 | Nathaniel 52 | Percy 53 | Paulette 54 | Petunia 55 | Randolph 56 | Rachael 57 | Roxanne 58 | Quentin 59 | Quinta 60 | Quincy 61 | Simon 62 | Sarah 63 | Sophie 64 | Ursula 65 | Umberto 66 | Ulrich 67 | Tabitha 68 | Tallulah 69 | Tomas 70 | Veronica 71 | Venitia 72 | Virgil 73 | Xanathe 74 | Xavier 75 | Xerxes 76 | Wallis 77 | Wendy 78 | Warwick 79 | Yasmin 80 | Yvette 81 | Yehudi 82 | Zelda 83 | Zak 84 | Zebulon 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /Chapter06/NamesApp/NamesApp/NamesApp-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFiles 12 | 13 | CFBundleIdentifier 14 | uk.co.charismaticmegafauna.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Chapter06/NamesApp/NamesApp/NamesApp-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'NamesApp' target in the 'NamesApp' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Chapter06/NamesApp/NamesApp/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Chapter06/NamesApp/NamesApp/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // NamesApp 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. 7 | // See license.txt for licensing information. 8 | 9 | #import 10 | 11 | #import "NAAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([NAAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter06/SimpleIndexedTable/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter06/SimpleIndexedTable/.DS_Store -------------------------------------------------------------------------------- /Chapter06/SimpleIndexedTable/SimpleIndexedTable/CMAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // CMAppDelegate.h 3 | // SimpleIndexedTable 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. 7 | // See license.txt for licensing information. 8 | 9 | #import 10 | 11 | @class CMViewController; 12 | 13 | @interface CMAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) CMViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Chapter06/SimpleIndexedTable/SimpleIndexedTable/CMAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // CMAppDelegate.m 3 | // SimpleIndexedTable 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. 7 | // See license.txt for licensing information. 8 | 9 | #import "CMAppDelegate.h" 10 | 11 | #import "CMViewController.h" 12 | 13 | @implementation CMAppDelegate 14 | 15 | @synthesize window = _window; 16 | @synthesize viewController = _viewController; 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 19 | { 20 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 21 | // Override point for customization after application launch. 22 | self.viewController = [[CMViewController alloc] initWithNibName:@"CMViewController" bundle:nil]; 23 | self.window.rootViewController = self.viewController; 24 | [self.window makeKeyAndVisible]; 25 | return YES; 26 | } 27 | 28 | - (void)applicationWillResignActive:(UIApplication *)application 29 | { 30 | /* 31 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 32 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 33 | */ 34 | } 35 | 36 | - (void)applicationDidEnterBackground:(UIApplication *)application 37 | { 38 | /* 39 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 40 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 41 | */ 42 | } 43 | 44 | - (void)applicationWillEnterForeground:(UIApplication *)application 45 | { 46 | /* 47 | Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 48 | */ 49 | } 50 | 51 | - (void)applicationDidBecomeActive:(UIApplication *)application 52 | { 53 | /* 54 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 55 | */ 56 | } 57 | 58 | - (void)applicationWillTerminate:(UIApplication *)application 59 | { 60 | /* 61 | Called when the application is about to terminate. 62 | Save data if appropriate. 63 | See also applicationDidEnterBackground:. 64 | */ 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Chapter06/SimpleIndexedTable/SimpleIndexedTable/CMViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CMViewController.h 3 | // SimpleIndexedTable 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. 7 | // See license.txt for licensing information. 8 | 9 | #import 10 | 11 | @interface CMViewController : UIViewController 12 | 13 | @property (nonatomic, strong) NSArray *tableData; 14 | @property (nonatomic, strong) NSArray *indexTitlesArray; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Chapter06/SimpleIndexedTable/SimpleIndexedTable/CMViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CMViewController.m 3 | // SimpleIndexedTable 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. 7 | // See license.txt for licensing information. 8 | 9 | #import "CMViewController.h" 10 | 11 | @implementation CMViewController 12 | 13 | @synthesize tableData; 14 | @synthesize indexTitlesArray; 15 | 16 | - (void)didReceiveMemoryWarning 17 | { 18 | [super didReceiveMemoryWarning]; 19 | // Release any cached data, images, etc that aren't in use. 20 | } 21 | 22 | #pragma mark - Table View methods 23 | 24 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 25 | 26 | static NSString *cellIdentifier = @"cellIdentifier"; 27 | 28 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 29 | 30 | if (!cell) { 31 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; 32 | } 33 | 34 | cell.textLabel.text = [self.tableData objectAtIndex:indexPath.section]; 35 | 36 | return cell; 37 | 38 | } 39 | 40 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 41 | return 1; 42 | } 43 | 44 | -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 45 | return [self.indexTitlesArray count]; 46 | } 47 | 48 | -(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 49 | return [self.indexTitlesArray objectAtIndex:section]; 50 | } 51 | 52 | -(NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView { 53 | return self.indexTitlesArray; 54 | } 55 | 56 | -(NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index { 57 | return [self.indexTitlesArray indexOfObject:title]; 58 | } 59 | 60 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 61 | 62 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 63 | 64 | } 65 | 66 | #pragma mark - View lifecycle 67 | 68 | - (void)viewDidLoad 69 | { 70 | [super viewDidLoad]; 71 | // Do any additional setup after loading the view, typically from a nib. 72 | 73 | self.tableData = [[NSArray alloc] initWithObjects:@"Aaron", @"Bailey", @"Cadan", @"Dafydd", @"Eamonn", @"Fabian", @"Gabrielle", @"Hafwen", @"Isaac", @"Jacinta", @"Kathleen", @"Lucy", @"Maurice", @"Nadia", @"Octavia", @"Padraig", @"Quinta", @"Rachel", @"Sabina", @"Tabitha", @"Uma", @"Valentina", @"Wallis", @"Xanthe", @"Yvonne", @"Zebediah", nil]; 74 | 75 | NSString *letters = @"A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"; 76 | self.indexTitlesArray = [letters componentsSeparatedByString:@" "]; 77 | 78 | } 79 | 80 | - (void)viewDidUnload 81 | { 82 | [super viewDidUnload]; 83 | // Release any retained subviews of the main view. 84 | // e.g. self.myOutlet = nil; 85 | self.tableData = nil; 86 | self.indexTitlesArray = nil; 87 | 88 | } 89 | 90 | - (void)viewWillAppear:(BOOL)animated 91 | { 92 | [super viewWillAppear:animated]; 93 | } 94 | 95 | - (void)viewDidAppear:(BOOL)animated 96 | { 97 | [super viewDidAppear:animated]; 98 | } 99 | 100 | - (void)viewWillDisappear:(BOOL)animated 101 | { 102 | [super viewWillDisappear:animated]; 103 | } 104 | 105 | - (void)viewDidDisappear:(BOOL)animated 106 | { 107 | [super viewDidDisappear:animated]; 108 | } 109 | 110 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 111 | { 112 | // Return YES for supported orientations 113 | return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 114 | } 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /Chapter06/SimpleIndexedTable/SimpleIndexedTable/License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Chapter06/SimpleIndexedTable/SimpleIndexedTable/SimpleIndexedTable-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFiles 12 | 13 | CFBundleIdentifier 14 | uk.co.charismaticmegafauna.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Chapter06/SimpleIndexedTable/SimpleIndexedTable/SimpleIndexedTable-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SimpleIndexedTable' target in the 'SimpleIndexedTable' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Chapter06/SimpleIndexedTable/SimpleIndexedTable/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Chapter06/SimpleIndexedTable/SimpleIndexedTable/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SimpleIndexedTable 4 | // 5 | // Created by Tim Duckett on 04/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. 7 | // See license.txt for licensing information. 8 | 9 | #import 10 | 11 | #import "CMAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([CMAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter07/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter07/.DS_Store -------------------------------------------------------------------------------- /Chapter07/EditingApp/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter07/EditingApp/.DS_Store -------------------------------------------------------------------------------- /Chapter07/EditingApp/EditingApp/CMAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // CMAppDelegate.h 3 | // EditingApp 4 | // 5 | // Created by TimD on 05/02/2012. 6 | // Copyright (c) Tim Duckett / Charismatic Megafauna Ltd. Some rights reserved. 7 | // See License.txt for licensing information. 8 | 9 | #import 10 | 11 | @class CMViewController; 12 | 13 | @interface CMAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) CMViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Chapter07/EditingApp/EditingApp/CMAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // CMAppDelegate.m 3 | // EditingApp 4 | // 5 | // Created by TimD on 05/02/2012. 6 | // Copyright (c) Tim Duckett / Charismatic Megafauna Ltd. Some rights reserved. 7 | // See License.txt for licensing information. 8 | 9 | 10 | #import "CMAppDelegate.h" 11 | 12 | #import "CMViewController.h" 13 | 14 | @implementation CMAppDelegate 15 | 16 | @synthesize window = _window; 17 | @synthesize viewController = _viewController; 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 20 | { 21 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 22 | // Override point for customization after application launch. 23 | 24 | UIViewController *vC = [[CMViewController alloc] initWithNibName:@"CMViewController" bundle:nil]; 25 | 26 | UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:vC]; 27 | 28 | self.window.rootViewController = navController; 29 | 30 | [self.window makeKeyAndVisible]; 31 | 32 | return YES; 33 | } 34 | 35 | - (void)applicationWillResignActive:(UIApplication *)application 36 | { 37 | /* 38 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 39 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 40 | */ 41 | } 42 | 43 | - (void)applicationDidEnterBackground:(UIApplication *)application 44 | { 45 | /* 46 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 47 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 48 | */ 49 | } 50 | 51 | - (void)applicationWillEnterForeground:(UIApplication *)application 52 | { 53 | /* 54 | Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 55 | */ 56 | } 57 | 58 | - (void)applicationDidBecomeActive:(UIApplication *)application 59 | { 60 | /* 61 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 62 | */ 63 | } 64 | 65 | - (void)applicationWillTerminate:(UIApplication *)application 66 | { 67 | /* 68 | Called when the application is about to terminate. 69 | Save data if appropriate. 70 | See also applicationDidEnterBackground:. 71 | */ 72 | } 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /Chapter07/EditingApp/EditingApp/CMViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CMViewController.h 3 | // EditingApp 4 | // 5 | // Created by TimD on 05/02/2012. 6 | // Copyright (c) Tim Duckett / Charismatic Megafauna Ltd. Some rights reserved. 7 | // See License.txt for licensing information. 8 | 9 | 10 | #import 11 | 12 | @interface CMViewController : UIViewController 13 | 14 | @property (nonatomic, strong) NSMutableArray *tableData; 15 | @property (strong, nonatomic) IBOutlet UITableView *theTableView; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Chapter07/EditingApp/EditingApp/CMViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CMViewController.m 3 | // EditingApp 4 | // 5 | // Created by TimD on 05/02/2012. 6 | // Copyright (c) Tim Duckett / Charismatic Megafauna Ltd. Some rights reserved. 7 | // See License.txt for licensing information. 8 | 9 | 10 | #import "CMViewController.h" 11 | 12 | @implementation CMViewController 13 | 14 | @synthesize tableData; 15 | @synthesize theTableView; 16 | 17 | - (void)didReceiveMemoryWarning 18 | { 19 | [super didReceiveMemoryWarning]; 20 | // Release any cached data, images, etc that aren't in use. 21 | } 22 | 23 | #pragma mark - Table view methods 24 | 25 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 26 | return [self.tableData count] + 1; 27 | } 28 | 29 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 30 | 31 | static NSString *cellIdentifier = @"cellIdentifier"; 32 | 33 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 34 | 35 | if (!cell) { 36 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; 37 | } 38 | 39 | if (indexPath.row == [self.tableData count]) { 40 | 41 | cell.textLabel.text = @"Add new row"; 42 | cell.textLabel.textColor = [UIColor darkGrayColor]; 43 | 44 | } else { 45 | 46 | cell.textLabel.text = [self.tableData objectAtIndex:indexPath.row]; 47 | 48 | } 49 | 50 | return cell; 51 | 52 | } 53 | 54 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 55 | 56 | if (indexPath.row == [self.tableData count]) { 57 | 58 | // Puts table into editing mode 59 | [self setEditing:YES animated:YES]; 60 | 61 | } else { 62 | 63 | // Handle "normal" selection 64 | 65 | } 66 | } 67 | 68 | #pragma mark - Table editing methods 69 | 70 | -(void)setEditing:(BOOL)editing animated:(BOOL)animated { 71 | [super setEditing:editing animated:animated]; 72 | [theTableView setEditing:editing animated:animated]; 73 | } 74 | 75 | -(BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 76 | return YES; 77 | } 78 | 79 | -(UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath { 80 | 81 | if (self.editing) { 82 | 83 | if (indexPath.row == [self.tableData count]) { 84 | return UITableViewCellEditingStyleInsert; 85 | } else { 86 | return UITableViewCellEditingStyleDelete; 87 | } 88 | 89 | } 90 | 91 | return UITableViewCellEditingStyleNone; 92 | 93 | } 94 | 95 | -(void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 96 | 97 | NSArray *indexPathArray = [NSArray arrayWithObject:indexPath]; 98 | 99 | if (editingStyle == UITableViewCellEditingStyleDelete) { 100 | 101 | [self.tableData removeObjectAtIndex:indexPath.row]; 102 | 103 | [tableView deleteRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationAutomatic]; 104 | 105 | } else if (editingStyle == UITableViewCellEditingStyleInsert) { 106 | 107 | NSString *theObjectToInsert = [NSString stringWithFormat:@"%@", [NSDate date]]; 108 | [self.tableData addObject:theObjectToInsert]; 109 | [tableView insertRowsAtIndexPaths:indexPathArray withRowAnimation:UITableViewRowAnimationAutomatic]; 110 | 111 | } 112 | } 113 | 114 | -(BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { 115 | 116 | if (indexPath.row == [self.tableData count]) { 117 | return NO; 118 | } 119 | 120 | return YES; 121 | } 122 | 123 | -(NSIndexPath *)tableView:(UITableView *)tableView targetIndexPathForMoveFromRowAtIndexPath:(NSIndexPath *)sourceIndexPath toProposedIndexPath:(NSIndexPath *)proposedDestinationIndexPath { 124 | 125 | if (proposedDestinationIndexPath.row == [self.tableData count]) { 126 | return sourceIndexPath; 127 | } 128 | 129 | return proposedDestinationIndexPath; 130 | } 131 | 132 | -(void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath { 133 | 134 | [self.tableData insertObject:[self.tableData objectAtIndex:sourceIndexPath.row] atIndex:destinationIndexPath.row]; 135 | [self.tableData removeObjectAtIndex:(sourceIndexPath.row + 1)]; 136 | 137 | } 138 | 139 | #pragma mark - View lifecycle 140 | 141 | - (void)viewDidLoad 142 | { 143 | [super viewDidLoad]; 144 | // Do any additional setup after loading the view, typically from a nib. 145 | 146 | self.navigationItem.title = @"Row insertion"; 147 | self.navigationItem.rightBarButtonItem = self.editButtonItem; 148 | 149 | self.tableData = [[NSMutableArray alloc] initWithObjects:@"One", @"Two", @"Three", @"Four", @"Five", nil]; 150 | } 151 | 152 | - (void)viewDidUnload 153 | { 154 | [self setTheTableView:nil]; 155 | [super viewDidUnload]; 156 | // Release any retained subviews of the main view. 157 | // e.g. self.myOutlet = nil; 158 | self.tableData = nil; 159 | self.theTableView = nil; 160 | 161 | } 162 | 163 | - (void)viewWillAppear:(BOOL)animated 164 | { 165 | [super viewWillAppear:animated]; 166 | } 167 | 168 | - (void)viewDidAppear:(BOOL)animated 169 | { 170 | [super viewDidAppear:animated]; 171 | } 172 | 173 | - (void)viewWillDisappear:(BOOL)animated 174 | { 175 | [super viewWillDisappear:animated]; 176 | } 177 | 178 | - (void)viewDidDisappear:(BOOL)animated 179 | { 180 | [super viewDidDisappear:animated]; 181 | } 182 | 183 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 184 | { 185 | // Return YES for supported orientations 186 | return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 187 | } 188 | 189 | @end 190 | -------------------------------------------------------------------------------- /Chapter07/EditingApp/EditingApp/EditingApp-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFiles 12 | 13 | CFBundleIdentifier 14 | uk.co.charismaticmegafauna.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Chapter07/EditingApp/EditingApp/EditingApp-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'EditingApp' target in the 'EditingApp' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Chapter07/EditingApp/EditingApp/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Chapter07/EditingApp/EditingApp/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // EditingApp 4 | // 5 | // Created by TimD on 05/02/2012. 6 | // Copyright (c) Tim Duckett / Charismatic Megafauna Ltd. Some rights reserved. 7 | // See License.txt for licensing information. 8 | 9 | 10 | #import 11 | 12 | #import "CMAppDelegate.h" 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | @autoreleasepool { 17 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([CMAppDelegate class])); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chapter07/EditingApp/License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Chapter08/CellsFromNibs/CellsFromNibs/CMAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // CMAppDelegate.h 3 | // CellsFromNibs 4 | // 5 | // Created by Tim Duckett on 19/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class CMViewController; 12 | 13 | @interface CMAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) CMViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Chapter08/CellsFromNibs/CellsFromNibs/CMAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // CMAppDelegate.m 3 | // CellsFromNibs 4 | // 5 | // Created by Tim Duckett on 19/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import "CMAppDelegate.h" 10 | 11 | #import "CMViewController.h" 12 | 13 | @implementation CMAppDelegate 14 | 15 | @synthesize window = _window; 16 | @synthesize viewController = _viewController; 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 19 | { 20 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 21 | // Override point for customization after application launch. 22 | self.viewController = [[CMViewController alloc] initWithNibName:@"CMViewController" bundle:nil]; 23 | self.window.rootViewController = self.viewController; 24 | [self.window makeKeyAndVisible]; 25 | return YES; 26 | } 27 | 28 | - (void)applicationWillResignActive:(UIApplication *)application 29 | { 30 | /* 31 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 32 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 33 | */ 34 | } 35 | 36 | - (void)applicationDidEnterBackground:(UIApplication *)application 37 | { 38 | /* 39 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 40 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 41 | */ 42 | } 43 | 44 | - (void)applicationWillEnterForeground:(UIApplication *)application 45 | { 46 | /* 47 | Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 48 | */ 49 | } 50 | 51 | - (void)applicationDidBecomeActive:(UIApplication *)application 52 | { 53 | /* 54 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 55 | */ 56 | } 57 | 58 | - (void)applicationWillTerminate:(UIApplication *)application 59 | { 60 | /* 61 | Called when the application is about to terminate. 62 | Save data if appropriate. 63 | See also applicationDidEnterBackground:. 64 | */ 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Chapter08/CellsFromNibs/CellsFromNibs/CMViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CMViewController.h 3 | // CellsFromNibs 4 | // 5 | // Created by Tim Duckett on 19/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CMViewController : UITableViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Chapter08/CellsFromNibs/CellsFromNibs/CMViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CMViewController.m 3 | // CellsFromNibs 4 | // 5 | // Created by Tim Duckett on 19/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import "CMViewController.h" 10 | 11 | @implementation CMViewController 12 | 13 | - (id)initWithStyle:(UITableViewStyle)style 14 | { 15 | self = [super initWithStyle:style]; 16 | if (self) { 17 | // Custom initialization 18 | } 19 | return self; 20 | } 21 | 22 | - (void)didReceiveMemoryWarning 23 | { 24 | // Releases the view if it doesn't have a superview. 25 | [super didReceiveMemoryWarning]; 26 | 27 | // Release any cached data, images, etc that aren't in use. 28 | } 29 | 30 | #pragma mark - View lifecycle 31 | 32 | - (void)viewDidLoad 33 | { 34 | [super viewDidLoad]; 35 | 36 | // Uncomment the following line to preserve selection between presentations. 37 | // self.clearsSelectionOnViewWillAppear = NO; 38 | 39 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 40 | // self.navigationItem.rightBarButtonItem = self.editButtonItem; 41 | } 42 | 43 | - (void)viewDidUnload 44 | { 45 | [super viewDidUnload]; 46 | // Release any retained subviews of the main view. 47 | // e.g. self.myOutlet = nil; 48 | } 49 | 50 | - (void)viewWillAppear:(BOOL)animated 51 | { 52 | [super viewWillAppear:animated]; 53 | } 54 | 55 | - (void)viewDidAppear:(BOOL)animated 56 | { 57 | [super viewDidAppear:animated]; 58 | } 59 | 60 | - (void)viewWillDisappear:(BOOL)animated 61 | { 62 | [super viewWillDisappear:animated]; 63 | } 64 | 65 | - (void)viewDidDisappear:(BOOL)animated 66 | { 67 | [super viewDidDisappear:animated]; 68 | } 69 | 70 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 71 | { 72 | // Return YES for supported orientations 73 | return (interfaceOrientation == UIInterfaceOrientationPortrait); 74 | } 75 | 76 | #pragma mark - Table view data source 77 | 78 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 79 | { 80 | // Return the number of sections. 81 | return 1; 82 | } 83 | 84 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 85 | { 86 | // Return the number of rows in the section. 87 | return 10; 88 | } 89 | 90 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 91 | { 92 | static NSString *CellIdentifier = @"CellIdentifier"; 93 | 94 | [tableView registerNib:[UINib nibWithNibName:@"NewCell" bundle:nil] forCellReuseIdentifier:CellIdentifier]; 95 | 96 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 97 | 98 | /* 99 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 100 | 101 | if (cell == nil) { 102 | //cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 103 | // cell = [[[NSBundle mainBundle] loadNibNamed:@"NewCell" owner:self options:nil] lastObject]; 104 | UINib *theNib = [UINib nibWithNibName:@"NewCell" bundle:nil]; 105 | cell = [[theNib instantiateWithOwner:self options:nil] lastObject]; 106 | } 107 | */ 108 | // Configure the cell... 109 | UILabel *theTitleLabel = (UILabel *)[cell viewWithTag:1000]; 110 | UILabel *theSubtitle = (UILabel *)[cell viewWithTag:1010]; 111 | UILabel *theSubSubTitle = (UILabel *)[cell viewWithTag:1020]; 112 | 113 | [theTitleLabel setText:[NSString stringWithFormat:@"Row %d", indexPath.row]]; 114 | [theSubtitle setText:[NSString stringWithFormat:@"Number %d", indexPath.row]]; 115 | [theSubSubTitle setText:[NSString stringWithFormat:@"This is row %d", indexPath.row]]; 116 | 117 | return cell; 118 | } 119 | 120 | 121 | // Override to support conditional editing of the table view. 122 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 123 | { 124 | // Return NO if you do not want the specified item to be editable. 125 | return YES; 126 | } 127 | 128 | 129 | 130 | // Override to support editing the table view. 131 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 132 | { 133 | if (editingStyle == UITableViewCellEditingStyleDelete) { 134 | // Delete the row from the data source 135 | [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 136 | } 137 | else if (editingStyle == UITableViewCellEditingStyleInsert) { 138 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 139 | } 140 | } 141 | 142 | 143 | 144 | // Override to support rearranging the table view. 145 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath 146 | { 147 | } 148 | 149 | 150 | 151 | // Override to support conditional rearranging of the table view. 152 | - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath 153 | { 154 | // Return NO if you do not want the item to be re-orderable. 155 | return YES; 156 | } 157 | 158 | 159 | #pragma mark - Table view delegate 160 | 161 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 162 | { 163 | // Navigation logic may go here. Create and push another view controller. 164 | /* 165 | <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil]; 166 | // ... 167 | // Pass the selected object to the new view controller. 168 | [self.navigationController pushViewController:detailViewController animated:YES]; 169 | */ 170 | } 171 | 172 | @end 173 | -------------------------------------------------------------------------------- /Chapter08/CellsFromNibs/CellsFromNibs/CMViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1280 5 | 11C25 6 | 1919 7 | 1138.11 8 | 566.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 916 12 | 13 | 14 | IBProxyObject 15 | IBUITableView 16 | 17 | 18 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 19 | 20 | 21 | PluginDependencyRecalculationVersion 22 | 23 | 24 | 25 | 26 | IBFilesOwner 27 | IBCocoaTouchFramework 28 | 29 | 30 | IBFirstResponder 31 | IBCocoaTouchFramework 32 | 33 | 34 | 35 | 274 36 | {{0, 20}, {320, 460}} 37 | 38 | 39 | 40 | 41 | 3 42 | MQA 43 | 44 | NO 45 | YES 46 | NO 47 | 48 | IBCocoaTouchFramework 49 | NO 50 | 1 51 | 0 52 | YES 53 | 44 54 | 22 55 | 22 56 | 57 | 58 | 59 | 60 | 61 | 62 | view 63 | 64 | 65 | 66 | 5 67 | 68 | 69 | 70 | dataSource 71 | 72 | 73 | 74 | 6 75 | 76 | 77 | 78 | delegate 79 | 80 | 81 | 82 | 7 83 | 84 | 85 | 86 | 87 | 88 | 0 89 | 90 | 91 | 92 | 93 | 94 | -1 95 | 96 | 97 | File's Owner 98 | 99 | 100 | -2 101 | 102 | 103 | 104 | 105 | 4 106 | 107 | 108 | 109 | 110 | 111 | 112 | CMViewController 113 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 114 | UIResponder 115 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 116 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 117 | 118 | 119 | 120 | 121 | 122 | 7 123 | 124 | 125 | 126 | 127 | CMViewController 128 | UIViewController 129 | 130 | IBProjectSource 131 | ./Classes/CMViewController.h 132 | 133 | 134 | 135 | 136 | 0 137 | IBCocoaTouchFramework 138 | YES 139 | 3 140 | 916 141 | 142 | 143 | -------------------------------------------------------------------------------- /Chapter08/CellsFromNibs/CellsFromNibs/CellsFromNibs-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFiles 12 | 13 | CFBundleIdentifier 14 | uk.co.charismaticmegafauna.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Chapter08/CellsFromNibs/CellsFromNibs/CellsFromNibs-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'CellsFromNibs' target in the 'CellsFromNibs' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Chapter08/CellsFromNibs/CellsFromNibs/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Chapter08/CellsFromNibs/CellsFromNibs/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // CellsFromNibs 4 | // 5 | // Created by Tim Duckett on 19/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "CMAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([CMAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter08/CellsFromNibs/License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/CodeCustomCells-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFiles 12 | 13 | CFBundleIdentifier 14 | uk.co.charismaticmegafauna.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/CodeCustomCells-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'MultiCustomCells' target in the 'MultiCustomCells' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/EvenCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // EvenCell.h 3 | // MultiCustomCells 4 | // 5 | // Created by Tim Duckett on 20/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface EvenCell : UITableViewCell 12 | 13 | @property (nonatomic, strong) UIImageView *iconView; 14 | @property (nonatomic, strong) UILabel *cellTitleLabel; 15 | @property (nonatomic, strong) UILabel *mainContentLabel; 16 | @property (nonatomic, strong) UILabel *otherContentLabel; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/EvenCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // EvenCell.m 3 | // MultiCustomCells 4 | // 5 | // Created by Tim Duckett on 20/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import "EvenCell.h" 10 | 11 | @implementation EvenCell 12 | 13 | @synthesize iconView = _iconView; 14 | @synthesize cellTitleLabel = _cellTitleLabel; 15 | @synthesize mainContentLabel = _mainContentLabel; 16 | @synthesize otherContentLabel = _otherContentLabel; 17 | 18 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 19 | { 20 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 21 | if (self) { 22 | 23 | // background view 24 | UIImageView *theBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"gingham"]]; 25 | self.backgroundView = theBackgroundView; 26 | 27 | // cellTitle label 28 | _cellTitleLabel = [[UILabel alloc] init]; 29 | _cellTitleLabel.frame = CGRectMake(13, 14, 173, 21); 30 | [_cellTitleLabel setBackgroundColor:[UIColor clearColor]]; 31 | [_cellTitleLabel setFont:[UIFont fontWithName:@"Baskerville-SemiBold" size:27]]; 32 | [_cellTitleLabel setTextColor:[UIColor blackColor]]; 33 | 34 | // mainContent label 35 | _mainContentLabel = [[UILabel alloc] init]; 36 | _mainContentLabel.frame = CGRectMake(110, 2, 147, 21); 37 | [_mainContentLabel setBackgroundColor:[UIColor clearColor]]; 38 | [_mainContentLabel setFont:[UIFont fontWithName:@"Baskerville-Italic" size:15]]; 39 | [_mainContentLabel setTextColor:[UIColor blueColor]]; 40 | 41 | // mainContent label 42 | _otherContentLabel = [[UILabel alloc] init]; 43 | _otherContentLabel.frame = CGRectMake(110, 26, 147, 21); 44 | [_otherContentLabel setBackgroundColor:[UIColor clearColor]]; 45 | [_otherContentLabel setFont:[UIFont fontWithName:@"Baskerville" size:15]]; 46 | [_otherContentLabel setTextColor:[UIColor blueColor]]; 47 | 48 | // iconView 49 | _iconView = [[UIImageView alloc] init]; 50 | _iconView.frame = CGRectMake(265, 2, 45, 45); 51 | 52 | // Set up contentView 53 | [self.contentView addSubview:_cellTitleLabel]; 54 | [self.contentView addSubview:_mainContentLabel]; 55 | [self.contentView addSubview:_otherContentLabel]; 56 | [self.contentView addSubview:_iconView]; 57 | 58 | } 59 | 60 | return self; 61 | 62 | } 63 | 64 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated 65 | { 66 | [super setSelected:selected animated:animated]; 67 | 68 | // Configure the view for the selected state 69 | if (selected) { 70 | 71 | UIImageView *theSelectedView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bluePrint"]]; 72 | self.selectedBackgroundView = theSelectedView; 73 | 74 | [_cellTitleLabel setTextColor:[UIColor redColor]]; 75 | 76 | } else { 77 | 78 | self.selectedBackgroundView = nil; 79 | [_cellTitleLabel setTextColor:[UIColor blackColor]]; 80 | 81 | } 82 | } 83 | 84 | @end 85 | -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/OddCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // OddCell.h 3 | // MultiCustomCells 4 | // 5 | // Created by Tim Duckett on 20/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface OddCell : UITableViewCell 12 | 13 | @property (nonatomic, strong) UILabel *cellTitleLabel; 14 | @property (nonatomic, strong) UILabel *cellContentLabel; 15 | @property (nonatomic, strong) UIImageView *iconView; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/OddCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // OddCell.m 3 | // MultiCustomCells 4 | // 5 | // Created by Tim Duckett on 20/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import "OddCell.h" 10 | 11 | @implementation OddCell 12 | 13 | @synthesize cellTitleLabel = _cellTitleLabel; 14 | @synthesize cellContentLabel = _cellContentLabel; 15 | @synthesize iconView = _iconView; 16 | 17 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 18 | { 19 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 20 | if (self) { 21 | // background view 22 | UIImageView *theBackgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"corkboard"]]; 23 | self.backgroundView = theBackgroundView; 24 | 25 | // cellTitle label 26 | _cellTitleLabel = [[UILabel alloc] init]; 27 | _cellTitleLabel.frame = CGRectMake(92, 13, 208, 32); 28 | [_cellTitleLabel setBackgroundColor:[UIColor clearColor]]; 29 | [_cellTitleLabel setFont:[UIFont fontWithName:@"Futura-CondensedExtraBold" size:23]]; 30 | [_cellTitleLabel setTextColor:[UIColor blackColor]]; 31 | 32 | // cellContent label 33 | _cellContentLabel = [[UILabel alloc] init]; 34 | _cellContentLabel.frame = CGRectMake(92, 42, 208, 21); 35 | [_cellContentLabel setBackgroundColor:[UIColor clearColor]]; 36 | [_cellContentLabel setFont:[UIFont fontWithName:@"Futura-Medium" size:13]]; 37 | [_cellContentLabel setTextColor:[UIColor blackColor]]; 38 | 39 | // iconView 40 | _iconView = [[UIImageView alloc] init]; 41 | _iconView.frame = CGRectMake(20, 17, 58, 36); 42 | 43 | // Set up contentView 44 | [self.contentView addSubview:_cellTitleLabel]; 45 | [self.contentView addSubview:_cellContentLabel]; 46 | [self.contentView addSubview:_iconView]; 47 | 48 | } 49 | 50 | return self; 51 | 52 | } 53 | 54 | -(void)drawRect:(CGRect)rect { 55 | 56 | 57 | 58 | } 59 | 60 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated 61 | { 62 | [super setSelected:selected animated:animated]; 63 | 64 | // Configure the view for the selected state 65 | if (selected) { 66 | 67 | UIImageView *theSelectedView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"bluePrint"]]; 68 | self.selectedBackgroundView = theSelectedView; 69 | 70 | [_cellTitleLabel setTextColor:[UIColor redColor]]; 71 | 72 | } else { 73 | 74 | self.selectedBackgroundView = nil; 75 | [_cellTitleLabel setTextColor:[UIColor blackColor]]; 76 | 77 | } 78 | } 79 | 80 | @end 81 | -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/TVAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // TVAppDelegate.h 3 | // MultiCustomCells 4 | // 5 | // Created by Tim Duckett on 20/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class TVViewController; 12 | 13 | @interface TVAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) TVViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/TVAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // TVAppDelegate.m 3 | // MultiCustomCells 4 | // 5 | // Created by Tim Duckett on 20/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import "TVAppDelegate.h" 10 | 11 | #import "TVTableController.h" 12 | 13 | @implementation TVAppDelegate 14 | 15 | @synthesize window = _window; 16 | @synthesize viewController = _viewController; 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 19 | { 20 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 21 | // Override point for customization after application launch. 22 | TVTableController *tableController = [[TVTableController alloc] initWithNibName:@"TVTableController" bundle:nil]; 23 | self.window.rootViewController = tableController; 24 | [self.window makeKeyAndVisible]; 25 | return YES; 26 | } 27 | 28 | - (void)applicationWillResignActive:(UIApplication *)application 29 | { 30 | /* 31 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 32 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 33 | */ 34 | } 35 | 36 | - (void)applicationDidEnterBackground:(UIApplication *)application 37 | { 38 | /* 39 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 40 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 41 | */ 42 | } 43 | 44 | - (void)applicationWillEnterForeground:(UIApplication *)application 45 | { 46 | /* 47 | Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 48 | */ 49 | } 50 | 51 | - (void)applicationDidBecomeActive:(UIApplication *)application 52 | { 53 | /* 54 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 55 | */ 56 | } 57 | 58 | - (void)applicationWillTerminate:(UIApplication *)application 59 | { 60 | /* 61 | Called when the application is about to terminate. 62 | Save data if appropriate. 63 | See also applicationDidEnterBackground:. 64 | */ 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/TVTableController.h: -------------------------------------------------------------------------------- 1 | // 2 | // TVTableController.h 3 | // MultiCustomCells 4 | // 5 | // Created by Tim Duckett on 20/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TVTableController : UITableViewController 12 | 13 | @property (nonatomic, retain) NSMutableArray *tableData; 14 | @property (nonatomic, retain) NSMutableArray *phraseData; 15 | 16 | @property (nonatomic, strong) NSString *cellIdentifier; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/TVTableController.m: -------------------------------------------------------------------------------- 1 | // 2 | // TVTableController.m 3 | // MultiCustomCells 4 | // 5 | // Created by Tim Duckett on 20/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import "TVTableController.h" 10 | 11 | #import "OddCell.h" 12 | #import "EvenCell.h" 13 | 14 | #define kOddCellIdentifier @"OddCellIdentifier" 15 | #define kEvenCellIdentifier @"EvenCellIdentifier" 16 | 17 | @implementation TVTableController 18 | 19 | @synthesize tableData = _tableData; 20 | @synthesize phraseData = _phraseData; 21 | @synthesize cellIdentifier = _cellIdentifier; 22 | 23 | - (id)initWithStyle:(UITableViewStyle)style 24 | { 25 | self = [super initWithStyle:style]; 26 | if (self) { 27 | // Custom initialization 28 | } 29 | return self; 30 | } 31 | 32 | - (void)didReceiveMemoryWarning 33 | { 34 | // Releases the view if it doesn't have a superview. 35 | [super didReceiveMemoryWarning]; 36 | 37 | // Release any cached data, images, etc that aren't in use. 38 | } 39 | 40 | #pragma mark - View lifecycle 41 | 42 | - (void)viewDidLoad 43 | { 44 | [super viewDidLoad]; 45 | 46 | // Uncomment the following line to preserve selection between presentations. 47 | // self.clearsSelectionOnViewWillAppear = NO; 48 | 49 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 50 | // self.navigationItem.rightBarButtonItem = self.editButtonItem; 51 | 52 | _tableData = [[NSMutableArray alloc] init]; 53 | _phraseData = [[NSMutableArray alloc] init]; 54 | 55 | NSArray *firstLatinWords = [NSArray arrayWithObjects:@"Lorem", @"Ipsum", @"Dolor", @"Amet", @"Consectetur", @"Adipiscing", @"Elit", @"Quisque", nil]; 56 | NSArray *secondLatinWords = [NSArray arrayWithObjects:@"vivamus", @"suscipit", @"ultricies", @"risus", @"in", @"consequat", @"vestibulum", @"laoreet", @"sollicitudin", @"velit", nil]; 57 | 58 | for (NSInteger i=0; i < 30; i++) { 59 | 60 | int firstWord = arc4random() % 7; 61 | int secondWord = arc4random() % 9; 62 | int thirdWord = arc4random() % 9; 63 | 64 | [_phraseData addObject:[NSString stringWithFormat:@"%@ %@ %@", [firstLatinWords objectAtIndex:firstWord], 65 | [secondLatinWords objectAtIndex:secondWord], 66 | [secondLatinWords objectAtIndex:thirdWord]]]; 67 | 68 | [_tableData addObject:[NSString stringWithFormat:@"Cell %d", i]]; 69 | } 70 | 71 | 72 | } 73 | 74 | - (void)viewDidUnload 75 | { 76 | [super viewDidUnload]; 77 | // Release any retained subviews of the main view. 78 | // e.g. self.myOutlet = nil; 79 | self.tableData = nil; 80 | self.phraseData = nil; 81 | self.cellIdentifier =nil; 82 | } 83 | 84 | - (void)viewWillAppear:(BOOL)animated 85 | { 86 | [super viewWillAppear:animated]; 87 | } 88 | 89 | - (void)viewDidAppear:(BOOL)animated 90 | { 91 | [super viewDidAppear:animated]; 92 | } 93 | 94 | - (void)viewWillDisappear:(BOOL)animated 95 | { 96 | [super viewWillDisappear:animated]; 97 | } 98 | 99 | - (void)viewDidDisappear:(BOOL)animated 100 | { 101 | [super viewDidDisappear:animated]; 102 | } 103 | 104 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 105 | { 106 | // Return YES for supported orientations 107 | return (interfaceOrientation == UIInterfaceOrientationPortrait); 108 | } 109 | 110 | #pragma mark - Table view data source 111 | 112 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 113 | { 114 | // Return the number of sections. 115 | return 1; 116 | } 117 | 118 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 119 | { 120 | 121 | // Return the number of rows in the section. 122 | return [_tableData count]; 123 | } 124 | 125 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 126 | { 127 | 128 | BOOL isEvenRow = (indexPath.row % 2 == 0); 129 | 130 | NSString *cellTitle = [self.tableData objectAtIndex:indexPath.row]; 131 | NSString *cellPhraseContent = [self.phraseData objectAtIndex:indexPath.row]; 132 | 133 | if (isEvenRow) { 134 | NSString *cellIdentifier = @"EvenCell"; 135 | EvenCell *evenCell = (EvenCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 136 | 137 | if (!evenCell) { 138 | evenCell = [[EvenCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; 139 | } 140 | 141 | evenCell.cellTitleLabel.text = cellTitle; 142 | evenCell.mainContentLabel.text = cellPhraseContent; 143 | evenCell.otherContentLabel.text = [NSString stringWithFormat:@"%@", [NSDate date]]; 144 | evenCell.iconView.image = [UIImage imageNamed:@"star"]; 145 | 146 | return evenCell; 147 | 148 | } 149 | 150 | NSString *cellIdentifier = @"OddCell"; 151 | OddCell *oddCell = (OddCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 152 | 153 | if (!oddCell) { 154 | oddCell = [[OddCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; 155 | } 156 | 157 | oddCell.cellTitleLabel.text = cellTitle; 158 | oddCell.cellContentLabel.text = cellPhraseContent; 159 | oddCell.iconView.image = [UIImage imageNamed:@"planet"]; 160 | 161 | return oddCell; 162 | 163 | } 164 | 165 | -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 166 | 167 | if (indexPath.row % 2 == 0) { 168 | // Even row 169 | return 50; 170 | } 171 | 172 | // Odd row 173 | return 70; 174 | } 175 | 176 | /* 177 | // Override to support conditional editing of the table view. 178 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 179 | { 180 | // Return NO if you do not want the specified item to be editable. 181 | return YES; 182 | } 183 | */ 184 | 185 | /* 186 | // Override to support editing the table view. 187 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 188 | { 189 | if (editingStyle == UITableViewCellEditingStyleDelete) { 190 | // Delete the row from the data source 191 | [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 192 | } 193 | else if (editingStyle == UITableViewCellEditingStyleInsert) { 194 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 195 | } 196 | } 197 | */ 198 | 199 | /* 200 | // Override to support rearranging the table view. 201 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath 202 | { 203 | } 204 | */ 205 | 206 | /* 207 | // Override to support conditional rearranging of the table view. 208 | - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath 209 | { 210 | // Return NO if you do not want the item to be re-orderable. 211 | return YES; 212 | } 213 | */ 214 | 215 | #pragma mark - Table view delegate 216 | 217 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 218 | { 219 | NSLog(@"did select row %d", indexPath.row); 220 | 221 | } 222 | 223 | @end 224 | -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/TVTableController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1280 5 | 11C25 6 | 1919 7 | 1138.11 8 | 566.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 916 12 | 13 | 14 | IBProxyObject 15 | IBUITableView 16 | 17 | 18 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 19 | 20 | 21 | PluginDependencyRecalculationVersion 22 | 23 | 24 | 25 | 26 | IBFilesOwner 27 | IBCocoaTouchFramework 28 | 29 | 30 | IBFirstResponder 31 | IBCocoaTouchFramework 32 | 33 | 34 | 35 | 274 36 | {{0, 20}, {320, 460}} 37 | 38 | 39 | 40 | 41 | 3 42 | MQA 43 | 44 | NO 45 | YES 46 | NO 47 | 48 | IBCocoaTouchFramework 49 | NO 50 | 1 51 | 0 52 | YES 53 | 44 54 | 22 55 | 22 56 | 57 | 58 | 59 | 60 | 61 | 62 | view 63 | 64 | 65 | 66 | 5 67 | 68 | 69 | 70 | dataSource 71 | 72 | 73 | 74 | 6 75 | 76 | 77 | 78 | delegate 79 | 80 | 81 | 82 | 7 83 | 84 | 85 | 86 | 87 | 88 | 0 89 | 90 | 91 | 92 | 93 | 94 | -1 95 | 96 | 97 | File's Owner 98 | 99 | 100 | -2 101 | 102 | 103 | 104 | 105 | 4 106 | 107 | 108 | 109 | 110 | 111 | 112 | TVTableController 113 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 114 | UIResponder 115 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 116 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 117 | 118 | 119 | 120 | 121 | 122 | 7 123 | 124 | 125 | 126 | 127 | TVTableController 128 | UIViewController 129 | 130 | IBProjectSource 131 | ./Classes/TVTableController.h 132 | 133 | 134 | 135 | 136 | 0 137 | IBCocoaTouchFramework 138 | YES 139 | 3 140 | 916 141 | 142 | 143 | -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/bluePrint.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter09/CodeCustomCells/MultiCustomCells/bluePrint.png -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/corkboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter09/CodeCustomCells/MultiCustomCells/corkboard.png -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/gingham.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter09/CodeCustomCells/MultiCustomCells/gingham.png -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MultiCustomCells 4 | // 5 | // Created by Tim Duckett on 20/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "TVAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([TVAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/planet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter09/CodeCustomCells/MultiCustomCells/planet.png -------------------------------------------------------------------------------- /Chapter09/CodeCustomCells/MultiCustomCells/star.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter09/CodeCustomCells/MultiCustomCells/star.png -------------------------------------------------------------------------------- /Chapter10/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter10/.DS_Store -------------------------------------------------------------------------------- /Chapter10/SimpleCellControls/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter10/SimpleCellControls/.DS_Store -------------------------------------------------------------------------------- /Chapter10/SimpleCellControls/SCCTableController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCCTableController.h 3 | // SimpleCellControls 4 | // 5 | // Created by Tim Duckett on 03/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SCCTableController : UITableViewController 12 | 13 | @property (nonatomic, strong) NSArray *tableData; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Chapter10/SimpleCellControls/SCCTableController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCCTableController.m 3 | // SimpleCellControls 4 | // 5 | // Created by Tim Duckett on 03/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import "SCCTableController.h" 10 | #import "CustomCell.h" 11 | 12 | @interface SCCTableController() 13 | 14 | -(void)didTapButtonCell; 15 | 16 | @end 17 | 18 | @implementation SCCTableController 19 | 20 | @synthesize tableData = _tableData; 21 | 22 | - (id)initWithStyle:(UITableViewStyle)style 23 | { 24 | self = [super initWithStyle:style]; 25 | if (self) { 26 | // Custom initialization 27 | } 28 | return self; 29 | } 30 | 31 | - (void)didReceiveMemoryWarning 32 | { 33 | // Releases the view if it doesn't have a superview. 34 | [super didReceiveMemoryWarning]; 35 | 36 | // Release any cached data, images, etc that aren't in use. 37 | } 38 | 39 | #pragma mark - View lifecycle 40 | 41 | - (void)viewDidLoad 42 | { 43 | [super viewDidLoad]; 44 | 45 | // Uncomment the following line to preserve selection between presentations. 46 | // self.clearsSelectionOnViewWillAppear = NO; 47 | 48 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 49 | // self.navigationItem.rightBarButtonItem = self.editButtonItem; 50 | 51 | _tableData = [[NSArray alloc] initWithObjects:@"One", @"Two", @"Three", @"Four", @"Five", nil]; 52 | 53 | } 54 | 55 | - (void)viewDidUnload 56 | { 57 | [super viewDidUnload]; 58 | // Release any retained subviews of the main view. 59 | // e.g. self.myOutlet = nil; 60 | } 61 | 62 | - (void)viewWillAppear:(BOOL)animated 63 | { 64 | [super viewWillAppear:animated]; 65 | } 66 | 67 | - (void)viewDidAppear:(BOOL)animated 68 | { 69 | [super viewDidAppear:animated]; 70 | } 71 | 72 | - (void)viewWillDisappear:(BOOL)animated 73 | { 74 | [super viewWillDisappear:animated]; 75 | } 76 | 77 | - (void)viewDidDisappear:(BOOL)animated 78 | { 79 | [super viewDidDisappear:animated]; 80 | } 81 | 82 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 83 | { 84 | // Return YES for supported orientations 85 | return (interfaceOrientation == UIInterfaceOrientationPortrait); 86 | } 87 | 88 | #pragma mark - Table view data source 89 | 90 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 91 | { 92 | // Return the number of sections. 93 | return 1; 94 | } 95 | 96 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 97 | { 98 | // Return the number of rows in the section. 99 | return [_tableData count]; 100 | } 101 | 102 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 103 | { 104 | static NSString *CellIdentifier = @"Cell"; 105 | 106 | CustomCell *cell = (CustomCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 107 | if (cell == nil) { 108 | cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 109 | } 110 | 111 | cell.indexPath = indexPath; 112 | 113 | return cell; 114 | } 115 | 116 | // Override to support conditional editing of the table view. 117 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 118 | { 119 | // Return NO if you do not want the specified item to be editable. 120 | return YES; 121 | } 122 | 123 | 124 | // Override to support editing the table view. 125 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 126 | { 127 | if (editingStyle == UITableViewCellEditingStyleDelete) { 128 | // Delete the row from the data source 129 | [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 130 | } 131 | else if (editingStyle == UITableViewCellEditingStyleInsert) { 132 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 133 | } 134 | } 135 | 136 | /* 137 | // Override to support rearranging the table view. 138 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath 139 | { 140 | } 141 | */ 142 | 143 | /* 144 | // Override to support conditional rearranging of the table view. 145 | - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath 146 | { 147 | // Return NO if you do not want the item to be re-orderable. 148 | return YES; 149 | } 150 | */ 151 | 152 | #pragma mark - Table view delegate 153 | 154 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 155 | { 156 | 157 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 158 | 159 | } 160 | 161 | #pragma mark - 162 | #pragma mark Button methods 163 | 164 | -(void)didTapButtonCell { 165 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Something happened!" 166 | message:@"A button was tapped" 167 | delegate:nil 168 | cancelButtonTitle:@"OK" 169 | otherButtonTitles:nil]; 170 | [alert show]; 171 | } 172 | 173 | @end 174 | -------------------------------------------------------------------------------- /Chapter10/SimpleCellControls/SCCTableController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1280 5 | 11C25 6 | 1919 7 | 1138.11 8 | 566.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 916 12 | 13 | 14 | IBProxyObject 15 | IBUITableView 16 | 17 | 18 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 19 | 20 | 21 | PluginDependencyRecalculationVersion 22 | 23 | 24 | 25 | 26 | IBFilesOwner 27 | IBCocoaTouchFramework 28 | 29 | 30 | IBFirstResponder 31 | IBCocoaTouchFramework 32 | 33 | 34 | 35 | 274 36 | {{0, 20}, {320, 460}} 37 | 38 | 39 | 40 | 41 | 3 42 | MQA 43 | 44 | NO 45 | YES 46 | NO 47 | 48 | IBCocoaTouchFramework 49 | NO 50 | 1 51 | 0 52 | YES 53 | 44 54 | 22 55 | 22 56 | 57 | 58 | 59 | 60 | 61 | 62 | view 63 | 64 | 65 | 66 | 5 67 | 68 | 69 | 70 | dataSource 71 | 72 | 73 | 74 | 6 75 | 76 | 77 | 78 | delegate 79 | 80 | 81 | 82 | 7 83 | 84 | 85 | 86 | 87 | 88 | 0 89 | 90 | 91 | 92 | 93 | 94 | -1 95 | 96 | 97 | File's Owner 98 | 99 | 100 | -2 101 | 102 | 103 | 104 | 105 | 4 106 | 107 | 108 | 109 | 110 | 111 | 112 | SCCTableController 113 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 114 | UIResponder 115 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 116 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 117 | 118 | 119 | 120 | 121 | 122 | 7 123 | 124 | 125 | 126 | 127 | SCCTableController 128 | UIViewController 129 | 130 | IBProjectSource 131 | ./Classes/SCCTableController.h 132 | 133 | 134 | 135 | 136 | 0 137 | IBCocoaTouchFramework 138 | YES 139 | 3 140 | 916 141 | 142 | 143 | -------------------------------------------------------------------------------- /Chapter10/SimpleCellControls/SimpleCellControls/CustomCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // CustomCell.h 3 | // SimpleCellControls 4 | // 5 | // Created by Tim Duckett on 03/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CustomCell : UITableViewCell 12 | 13 | @property (nonatomic, strong) NSIndexPath *indexPath; 14 | 15 | -(void)didTapButtonInCell; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Chapter10/SimpleCellControls/SimpleCellControls/CustomCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // CustomCell.m 3 | // SimpleCellControls 4 | // 5 | // Created by Tim Duckett on 03/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import "CustomCell.h" 10 | 11 | 12 | @implementation CustomCell 13 | 14 | @synthesize indexPath; 15 | 16 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 17 | { 18 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 19 | if (self) { 20 | // Initialization code 21 | UIButton *theButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 22 | [theButton setFrame:CGRectMake(0, 0, 75, 30)]; 23 | [theButton addTarget:self action:@selector(didTapButtonInCell) forControlEvents:UIControlEventTouchUpInside]; 24 | 25 | self.accessoryView = theButton; 26 | 27 | } 28 | return self; 29 | } 30 | 31 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated 32 | { 33 | [super setSelected:selected animated:animated]; 34 | 35 | // Configure the view for the selected state 36 | } 37 | 38 | -(void)setIndexPath:(NSIndexPath *)theIndexPath { 39 | 40 | indexPath = theIndexPath; 41 | 42 | UILabel *theLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 7, 200, 25)]; 43 | [theLabel setFont:[UIFont systemFontOfSize:18]]; 44 | [theLabel setText:[NSString stringWithFormat:@"Row %d", self.indexPath.row]]; 45 | 46 | [self.contentView addSubview:theLabel]; 47 | 48 | UIButton *theButton = (UIButton *)self.accessoryView; 49 | [theButton setTitle:@"Tap me!" forState:UIControlStateNormal]; 50 | 51 | } 52 | 53 | -(void)didTapButtonInCell { 54 | 55 | NSString *messageString = [NSString stringWithFormat:@"Button at section %d row %d was tapped.", self.indexPath.section, self.indexPath.row]; 56 | 57 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Button tapped!" message:messageString delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; 58 | 59 | [alert show]; 60 | 61 | } 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /Chapter10/SimpleCellControls/SimpleCellControls/License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Chapter10/SimpleCellControls/SimpleCellControls/SCCAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCCAppDelegate.h 3 | // SimpleCellControls 4 | // 5 | // Created by Tim Duckett on 03/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SCCViewController; 12 | 13 | @interface SCCAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) SCCViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Chapter10/SimpleCellControls/SimpleCellControls/SCCAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCCAppDelegate.m 3 | // SimpleCellControls 4 | // 5 | // Created by Tim Duckett on 03/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import "SCCAppDelegate.h" 10 | 11 | #import "SCCTableController.h" 12 | 13 | @implementation SCCAppDelegate 14 | 15 | @synthesize window = _window; 16 | @synthesize viewController = _viewController; 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 19 | { 20 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 21 | // Override point for customization after application launch. 22 | SCCTableController *sccTableController = [[SCCTableController alloc] initWithNibName:@"SCCTableController" bundle:nil]; 23 | 24 | self.window.rootViewController = sccTableController; 25 | 26 | [self.window makeKeyAndVisible]; 27 | return YES; 28 | } 29 | 30 | - (void)applicationWillResignActive:(UIApplication *)application 31 | { 32 | /* 33 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 34 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 35 | */ 36 | } 37 | 38 | - (void)applicationDidEnterBackground:(UIApplication *)application 39 | { 40 | /* 41 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 42 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 43 | */ 44 | } 45 | 46 | - (void)applicationWillEnterForeground:(UIApplication *)application 47 | { 48 | /* 49 | Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 50 | */ 51 | } 52 | 53 | - (void)applicationDidBecomeActive:(UIApplication *)application 54 | { 55 | /* 56 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 57 | */ 58 | } 59 | 60 | - (void)applicationWillTerminate:(UIApplication *)application 61 | { 62 | /* 63 | Called when the application is about to terminate. 64 | Save data if appropriate. 65 | See also applicationDidEnterBackground:. 66 | */ 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /Chapter10/SimpleCellControls/SimpleCellControls/SimpleCellControls-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFiles 12 | 13 | CFBundleIdentifier 14 | uk.co.charismaticmegafauna.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Chapter10/SimpleCellControls/SimpleCellControls/SimpleCellControls-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SimpleCellControls' target in the 'SimpleCellControls' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Chapter10/SimpleCellControls/SimpleCellControls/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Chapter10/SimpleCellControls/SimpleCellControls/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SimpleCellControls 4 | // 5 | // Created by Tim Duckett on 03/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SCCAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SCCAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter10/SimpleTaps/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter10/SimpleTaps/.DS_Store -------------------------------------------------------------------------------- /Chapter10/SimpleTaps/License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Chapter10/SimpleTaps/SimpleTaps/CMAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // CMAppDelegate.h 3 | // SimpleTaps 4 | // 5 | // Created by TimD on 05/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. Some rights reserved. 7 | // See License.txt for licensing information. 8 | 9 | #import 10 | 11 | @class CMViewController; 12 | 13 | @interface CMAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) CMViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Chapter10/SimpleTaps/SimpleTaps/CMAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // CMAppDelegate.m 3 | // SimpleTaps 4 | // 5 | // Created by TimD on 05/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. Some rights reserved. 7 | // See License.txt for licensing information. 8 | 9 | 10 | #import "CMAppDelegate.h" 11 | 12 | #import "CMViewController.h" 13 | 14 | @implementation CMAppDelegate 15 | 16 | @synthesize window = _window; 17 | @synthesize viewController = _viewController; 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 20 | { 21 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 22 | // Override point for customization after application launch. 23 | self.viewController = [[CMViewController alloc] initWithNibName:@"CMViewController" bundle:nil]; 24 | self.window.rootViewController = self.viewController; 25 | [self.window makeKeyAndVisible]; 26 | return YES; 27 | } 28 | 29 | - (void)applicationWillResignActive:(UIApplication *)application 30 | { 31 | /* 32 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 33 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 34 | */ 35 | } 36 | 37 | - (void)applicationDidEnterBackground:(UIApplication *)application 38 | { 39 | /* 40 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 41 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 42 | */ 43 | } 44 | 45 | - (void)applicationWillEnterForeground:(UIApplication *)application 46 | { 47 | /* 48 | Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 49 | */ 50 | } 51 | 52 | - (void)applicationDidBecomeActive:(UIApplication *)application 53 | { 54 | /* 55 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 56 | */ 57 | } 58 | 59 | - (void)applicationWillTerminate:(UIApplication *)application 60 | { 61 | /* 62 | Called when the application is about to terminate. 63 | Save data if appropriate. 64 | See also applicationDidEnterBackground:. 65 | */ 66 | } 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /Chapter10/SimpleTaps/SimpleTaps/CMViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // CMViewController.h 3 | // SimpleTaps 4 | // 5 | // Created by TimD on 05/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. Some rights reserved. 7 | // See License.txt for licensing information. 8 | 9 | 10 | #import 11 | 12 | @interface CMViewController : UIViewController 13 | 14 | @property (nonatomic, strong) NSArray *tableData; 15 | 16 | -(void)didTapButtonInCell; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Chapter10/SimpleTaps/SimpleTaps/CMViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // CMViewController.m 3 | // SimpleTaps 4 | // 5 | // Created by TimD on 05/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. Some rights reserved. 7 | // See License.txt for licensing information. 8 | 9 | 10 | #import "CMViewController.h" 11 | 12 | @implementation CMViewController 13 | 14 | @synthesize tableData; 15 | 16 | - (void)didReceiveMemoryWarning 17 | { 18 | [super didReceiveMemoryWarning]; 19 | // Release any cached data, images, etc that aren't in use. 20 | } 21 | 22 | #pragma mark - Table view methods 23 | 24 | -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 25 | return 1; 26 | } 27 | 28 | -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 29 | return [self.tableData count]; 30 | } 31 | 32 | -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 33 | 34 | static NSString *cellIdentifier = @"cellIdentifier"; 35 | 36 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier]; 37 | 38 | if (!cell) { 39 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]; 40 | } 41 | 42 | cell.textLabel.text = [self.tableData objectAtIndex:indexPath.row]; 43 | 44 | /* 45 | // Create and add the button to the cell 46 | UIButton *theButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 47 | [theButton setFrame:CGRectMake(235, 7, 75, 30)]; 48 | [theButton setTitle:@"Tap me!" forState:UIControlStateNormal]; 49 | [theButton addTarget:self action:@selector(didTapButtonInCell) forControlEvents:UIControlEventTouchUpInside]; 50 | 51 | [cell.contentView addSubview:theButton]; 52 | 53 | */ 54 | 55 | // Create and add the button to the accessory view 56 | UIButton *theButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 57 | 58 | // Set the X and Y coords of the button to 0 59 | [theButton setFrame:CGRectMake(0, 0, 75, 30)]; 60 | [theButton setTitle:@"Tap me!" forState:UIControlStateNormal]; 61 | [theButton addTarget:self action:@selector(didTapButtonInCell) forControlEvents:UIControlEventTouchUpInside]; 62 | 63 | // Add the button to the accessory view 64 | cell.accessoryView = theButton; 65 | 66 | return cell; 67 | } 68 | 69 | -(void)didTapButtonInCell { 70 | 71 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Something happened!" 72 | message:@"A button was tapped" 73 | delegate:nil 74 | cancelButtonTitle:@"OK" 75 | otherButtonTitles:nil]; 76 | [alert show]; 77 | 78 | } 79 | 80 | #pragma mark - View lifecycle 81 | 82 | - (void)viewDidLoad 83 | { 84 | [super viewDidLoad]; 85 | // Do any additional setup after loading the view, typically from a nib. 86 | 87 | self.tableData = [[NSArray alloc] initWithObjects:@"One", @"Two", @"Three", @"Four", @"Five", nil]; 88 | 89 | } 90 | 91 | - (void)viewDidUnload 92 | { 93 | [super viewDidUnload]; 94 | // Release any retained subviews of the main view. 95 | // e.g. self.myOutlet = nil; 96 | self.tableData = nil; 97 | } 98 | 99 | - (void)viewWillAppear:(BOOL)animated 100 | { 101 | [super viewWillAppear:animated]; 102 | } 103 | 104 | - (void)viewDidAppear:(BOOL)animated 105 | { 106 | [super viewDidAppear:animated]; 107 | } 108 | 109 | - (void)viewWillDisappear:(BOOL)animated 110 | { 111 | [super viewWillDisappear:animated]; 112 | } 113 | 114 | - (void)viewDidDisappear:(BOOL)animated 115 | { 116 | [super viewDidDisappear:animated]; 117 | } 118 | 119 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 120 | { 121 | // Return YES for supported orientations 122 | return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 123 | } 124 | 125 | @end 126 | -------------------------------------------------------------------------------- /Chapter10/SimpleTaps/SimpleTaps/SimpleTaps-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFiles 12 | 13 | CFBundleIdentifier 14 | uk.co.charismaticmegafauna.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /Chapter10/SimpleTaps/SimpleTaps/SimpleTaps-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SimpleTaps' target in the 'SimpleTaps' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Chapter10/SimpleTaps/SimpleTaps/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Chapter10/SimpleTaps/SimpleTaps/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SimpleTaps 4 | // 5 | // Created by TimD on 05/02/2012. 6 | // Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd. Some rights reserved. 7 | // See License.txt for licensing information. 8 | 9 | 10 | #import 11 | 12 | #import "CMAppDelegate.h" 13 | 14 | int main(int argc, char *argv[]) 15 | { 16 | @autoreleasepool { 17 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([CMAppDelegate class])); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Chapter10/SwipeAndPullRefreshTable/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter10/SwipeAndPullRefreshTable/.DS_Store -------------------------------------------------------------------------------- /Chapter10/SwipeAndPullRefreshTable/SwipingTable/License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Chapter10/SwipeAndPullRefreshTable/SwipingTable/SwipeAndPullRefreshTable-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFiles 12 | 13 | CFBundleIdentifier 14 | uk.co.charismaticmegafauna.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationPortraitUpsideDown 37 | UIInterfaceOrientationLandscapeLeft 38 | UIInterfaceOrientationLandscapeRight 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Chapter10/SwipeAndPullRefreshTable/SwipingTable/SwipeAndPullRefreshTable-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SwipingTable' target in the 'SwipingTable' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Chapter10/SwipeAndPullRefreshTable/SwipingTable/SwipeAndPullRefreshTableAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // CMAppDelegate.h 3 | // SwipingTable 4 | // 5 | // Created by Tim Duckett on 13/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface SwipeAndPullRefreshTableAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Chapter10/SwipeAndPullRefreshTable/SwipingTable/SwipeAndPullRefreshTableAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // CMAppDelegate.m 3 | // SwipingTable 4 | // 5 | // Created by Tim Duckett on 13/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import "SwipeAndPullRefreshTableAppDelegate.h" 10 | 11 | #import "SwipeTableController.h" 12 | 13 | @implementation SwipeAndPullRefreshTableAppDelegate 14 | 15 | @synthesize window = _window; 16 | 17 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 18 | { 19 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 20 | // Override point for customization after application launch. 21 | SwipeTableController *swipeVC = [[SwipeTableController alloc] initWithNibName:@"SwipeTableController" bundle:nil]; 22 | self.window.rootViewController = swipeVC; 23 | [self.window makeKeyAndVisible]; 24 | 25 | return YES; 26 | } 27 | 28 | - (void)applicationWillResignActive:(UIApplication *)application 29 | { 30 | /* 31 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 32 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 33 | */ 34 | } 35 | 36 | - (void)applicationDidEnterBackground:(UIApplication *)application 37 | { 38 | /* 39 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 40 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 41 | */ 42 | } 43 | 44 | - (void)applicationWillEnterForeground:(UIApplication *)application 45 | { 46 | /* 47 | Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 48 | */ 49 | } 50 | 51 | - (void)applicationDidBecomeActive:(UIApplication *)application 52 | { 53 | /* 54 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 55 | */ 56 | } 57 | 58 | - (void)applicationWillTerminate:(UIApplication *)application 59 | { 60 | /* 61 | Called when the application is about to terminate. 62 | Save data if appropriate. 63 | See also applicationDidEnterBackground:. 64 | */ 65 | } 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /Chapter10/SwipeAndPullRefreshTable/SwipingTable/SwipeCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeCell.h 3 | // SwipingTable 4 | // 5 | // Created by Tim Duckett on 13/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SwipeCellProtocol.h" 11 | 12 | @interface SwipeCell : UITableViewCell 13 | 14 | @property (nonatomic, strong) UIView *swipeView; 15 | @property (nonatomic, strong) UIView *topView; 16 | 17 | @property (nonatomic, retain) NSIndexPath *indexPath; 18 | @property (nonatomic, assign) id delegate; 19 | 20 | -(IBAction)didSwipeRightInCell:(id)sender; 21 | -(IBAction)didSwipeLeftInCell:(id)sender; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Chapter10/SwipeAndPullRefreshTable/SwipingTable/SwipeCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeCell.m 3 | // SwipingTable 4 | // 5 | // Created by Tim Duckett on 13/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import "SwipeCell.h" 10 | 11 | @implementation SwipeCell 12 | 13 | @synthesize swipeView = _swipeView; 14 | @synthesize topView = _topView; 15 | @synthesize indexPath = _indexPath; 16 | @synthesize delegate; 17 | 18 | - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 19 | { 20 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 21 | if (self) { 22 | // Initialization code 23 | 24 | // Create the top view 25 | _topView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.contentView.frame.size.width, 80)]; 26 | [_topView setBackgroundColor:[UIColor whiteColor]]; 27 | 28 | // Create the top label 29 | UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 20, 150, 40)]; 30 | [label setFont:[UIFont fontWithName:@"Zapfino" size:18]]; 31 | [label setTextColor:[UIColor blackColor]]; 32 | [label setText:@"Swipe me!"]; 33 | [_topView addSubview:label]; 34 | 35 | // Create the top image 36 | UIImageView *pointImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"point"]]; 37 | 38 | CGFloat pointImageXposition = self.contentView.frame.size.width - 160; 39 | [pointImage setFrame:CGRectMake(pointImageXposition, 18, 144, 44)]; 40 | [_topView addSubview:pointImage]; 41 | 42 | // Create the swipe view 43 | _swipeView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.contentView.frame.size.width, 80)]; 44 | [_swipeView setBackgroundColor:[UIColor darkGrayColor]]; 45 | 46 | // Create the swipe label 47 | UILabel *haveSwipedlabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 25, 200, 30)]; 48 | [haveSwipedlabel setFont:[UIFont fontWithName:@"GillSans-Bold" size:18]]; 49 | [haveSwipedlabel setTextColor:[UIColor whiteColor]]; 50 | [haveSwipedlabel setBackgroundColor:[UIColor darkGrayColor]]; 51 | [haveSwipedlabel setText:@"I've been swiped!"]; 52 | [_swipeView addSubview:haveSwipedlabel]; 53 | 54 | // Add views to contentView 55 | [self.contentView addSubview:_swipeView]; 56 | [self.contentView addSubview:_topView]; 57 | 58 | // Create the gesture recognizers 59 | UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(didSwipeRightInCell:)]; 60 | [swipeRight setDirection:UISwipeGestureRecognizerDirectionRight]; 61 | 62 | UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(didSwipeLeftInCell:)]; 63 | [swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft]; 64 | 65 | [self addGestureRecognizer:swipeRight]; 66 | [self addGestureRecognizer:swipeLeft]; 67 | 68 | // Prevent selection highlighting 69 | [self setSelectionStyle:UITableViewCellSelectionStyleNone]; 70 | 71 | } 72 | return self; 73 | } 74 | 75 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated 76 | { 77 | [super setSelected:selected animated:animated]; 78 | 79 | // Configure the view for the selected state 80 | } 81 | 82 | -(IBAction)didSwipeRightInCell:(id)sender { 83 | 84 | // Inform the delegate of the right swipe 85 | [delegate didSwipeRightInCellWithIndexPath:_indexPath]; 86 | 87 | [UIView setAnimationCurve:UIViewAnimationCurveEaseIn]; 88 | 89 | // Swipe top view left 90 | [UIView animateWithDuration:1.0 animations:^{ 91 | 92 | [_topView setFrame:CGRectMake(self.contentView.frame.size.width, 0, self.contentView.frame.size.width, 80)]; 93 | 94 | } completion:^(BOOL finished) { 95 | 96 | // Bounce lower view 97 | [UIView animateWithDuration:0.15 animations:^{ 98 | 99 | [_swipeView setFrame:CGRectMake(10, 0, self.contentView.frame.size.width, 80)]; 100 | 101 | } completion:^(BOOL finished) { 102 | 103 | [UIView animateWithDuration:0.15 animations:^{ 104 | [_swipeView setFrame:CGRectMake(0, 0, self.contentView.frame.size.width, 80)]; 105 | }]; 106 | }]; 107 | }]; 108 | 109 | } 110 | 111 | -(IBAction)didSwipeLeftInCell:(id)sender { 112 | 113 | // Inform the delegate of the left swipe 114 | [delegate didSwipeLeftInCellWithIndexPath:_indexPath]; 115 | 116 | [UIView setAnimationCurve:UIViewAnimationCurveEaseIn]; 117 | 118 | [UIView animateWithDuration:1.0 animations:^{ 119 | [_topView setFrame:CGRectMake(-10, 0, self.contentView.frame.size.width, 80)]; 120 | } completion:^(BOOL finished) { 121 | [UIView animateWithDuration:0.15 animations:^{ 122 | [_topView setFrame:CGRectMake(0, 0, self.contentView.frame.size.width, 80)]; 123 | }]; 124 | }]; 125 | 126 | } 127 | 128 | @end 129 | -------------------------------------------------------------------------------- /Chapter10/SwipeAndPullRefreshTable/SwipingTable/SwipeCellProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeCellProtocol.h 3 | // SwipingTable 4 | // 5 | // Created by Tim Duckett on 03/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol SwipeCellProtocol 12 | 13 | -(void)didSwipeRightInCellWithIndexPath:(NSIndexPath *)indexPath; 14 | -(void)didSwipeLeftInCellWithIndexPath:(NSIndexPath *)indexPath; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Chapter10/SwipeAndPullRefreshTable/SwipingTable/SwipeTableController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SwipeTableController.h 3 | // SwipingTable 4 | // 5 | // Created by Tim Duckett on 13/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SwipeCellProtocol.h" 11 | 12 | @interface SwipeTableController : UITableViewController 13 | 14 | @property (nonatomic, strong) NSIndexPath *swipedCell; 15 | 16 | @property (nonatomic, strong) UIWindow *mainWindow; 17 | @property (nonatomic, strong) UIActivityIndicatorView *activityIndicator; 18 | @property (nonatomic, strong) UIView *activityView; 19 | 20 | -(void)didSwipeRightInCellWithIndexPath:(NSIndexPath *)indexPath; 21 | -(void)didSwipeLeftInCellWithIndexPath:(NSIndexPath *)indexPath; 22 | 23 | -(void)displayActivitySpinner; 24 | -(void)removeActivitySpinner; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Chapter10/SwipeAndPullRefreshTable/SwipingTable/SwipeTableController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1280 5 | 11C74 6 | 1938 7 | 1138.23 8 | 567.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 933 12 | 13 | 14 | IBProxyObject 15 | IBUITableView 16 | 17 | 18 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 19 | 20 | 21 | PluginDependencyRecalculationVersion 22 | 23 | 24 | 25 | 26 | IBFilesOwner 27 | IBCocoaTouchFramework 28 | 29 | 30 | IBFirstResponder 31 | IBCocoaTouchFramework 32 | 33 | 34 | 35 | 274 36 | {320, 460} 37 | 38 | 39 | 40 | _NS:418 41 | 42 | 3 43 | MQA 44 | 45 | YES 46 | IBCocoaTouchFramework 47 | YES 48 | 1 49 | 0 50 | YES 51 | 44 52 | 22 53 | 22 54 | 55 | 56 | 57 | 58 | 59 | 60 | view 61 | 62 | 63 | 64 | 7 65 | 66 | 67 | 68 | dataSource 69 | 70 | 71 | 72 | 4 73 | 74 | 75 | 76 | delegate 77 | 78 | 79 | 80 | 5 81 | 82 | 83 | 84 | 85 | 86 | 0 87 | 88 | 89 | 90 | 91 | 92 | -1 93 | 94 | 95 | File's Owner 96 | 97 | 98 | -2 99 | 100 | 101 | 102 | 103 | 3 104 | 105 | 106 | 107 | 108 | 109 | 110 | SwipeTableController 111 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 112 | UIResponder 113 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 114 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 115 | 116 | 117 | 118 | 119 | 120 | 7 121 | 122 | 123 | 124 | 125 | SwipeTableController 126 | UITableViewController 127 | 128 | IBProjectSource 129 | ./Classes/SwipeTableController.h 130 | 131 | 132 | 133 | 134 | 0 135 | IBCocoaTouchFramework 136 | YES 137 | 3 138 | 933 139 | 140 | 141 | -------------------------------------------------------------------------------- /Chapter10/SwipeAndPullRefreshTable/SwipingTable/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Chapter10/SwipeAndPullRefreshTable/SwipingTable/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SwipingTable 4 | // 5 | // Created by Tim Duckett on 13/12/2011. 6 | // Copyright (c) 2011 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SwipeAndPullRefreshTableAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SwipeAndPullRefreshTableAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Chapter10/SwipeAndPullRefreshTable/SwipingTable/point.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter10/SwipeAndPullRefreshTable/SwipingTable/point.png -------------------------------------------------------------------------------- /Chapter11/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter11/.DS_Store -------------------------------------------------------------------------------- /Chapter11/SplitViewApp/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/timd/Pro-iOS-TableViews/3f14b54172e7ccfac405f8f2d110ea92f08b85e5/Chapter11/SplitViewApp/.DS_Store -------------------------------------------------------------------------------- /Chapter11/SplitViewApp/SplitViewApp/LeftTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LeftTableViewController.h 3 | // SplitViewApp 4 | // 5 | // Created by Tim Duckett on 04/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "UpdateSplitDetailViewProtocol.h" 11 | 12 | @interface LeftTableViewController : UITableViewController 13 | 14 | @property (nonatomic, weak) id delegate; 15 | 16 | @end 17 | -------------------------------------------------------------------------------- /Chapter11/SplitViewApp/SplitViewApp/LeftTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // LeftTableViewController.m 3 | // SplitViewApp 4 | // 5 | // Created by Tim Duckett on 04/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import "LeftTableViewController.h" 10 | 11 | @implementation LeftTableViewController 12 | 13 | @synthesize delegate; 14 | 15 | - (id)initWithStyle:(UITableViewStyle)style 16 | { 17 | self = [super initWithStyle:style]; 18 | if (self) { 19 | // Custom initialization 20 | } 21 | return self; 22 | } 23 | 24 | - (void)didReceiveMemoryWarning 25 | { 26 | // Releases the view if it doesn't have a superview. 27 | [super didReceiveMemoryWarning]; 28 | 29 | // Release any cached data, images, etc that aren't in use. 30 | } 31 | 32 | #pragma mark - View lifecycle 33 | 34 | - (void)viewDidLoad 35 | { 36 | [super viewDidLoad]; 37 | 38 | // Uncomment the following line to preserve selection between presentations. 39 | // self.clearsSelectionOnViewWillAppear = NO; 40 | 41 | // Uncomment the following line to display an Edit button in the navigation bar for this view controller. 42 | // self.navigationItem.rightBarButtonItem = self.editButtonItem; 43 | 44 | // Manage the size of the popover view 45 | self.contentSizeForViewInPopover = CGSizeMake(320.0, 300.0); 46 | 47 | // Persist the list view's selection state between appearances 48 | self.clearsSelectionOnViewWillAppear = NO; 49 | } 50 | 51 | - (void)viewDidUnload 52 | { 53 | [super viewDidUnload]; 54 | // Release any retained subviews of the main view. 55 | // e.g. self.myOutlet = nil; 56 | } 57 | 58 | - (void)viewWillAppear:(BOOL)animated 59 | { 60 | [super viewWillAppear:animated]; 61 | } 62 | 63 | - (void)viewDidAppear:(BOOL)animated 64 | { 65 | [super viewDidAppear:animated]; 66 | } 67 | 68 | - (void)viewWillDisappear:(BOOL)animated 69 | { 70 | [super viewWillDisappear:animated]; 71 | } 72 | 73 | - (void)viewDidDisappear:(BOOL)animated 74 | { 75 | [super viewDidDisappear:animated]; 76 | } 77 | 78 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 79 | { 80 | // Return YES for supported orientations 81 | return YES; 82 | } 83 | 84 | #pragma mark - Table view data source 85 | 86 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 87 | { 88 | // Return the number of sections. 89 | return 1; 90 | } 91 | 92 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 93 | { 94 | // Return the number of rows in the section. 95 | return 10; 96 | } 97 | 98 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 99 | { 100 | static NSString *CellIdentifier = @"Cell"; 101 | 102 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 103 | if (cell == nil) { 104 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; 105 | } 106 | 107 | // Configure the cell... 108 | cell.textLabel.text = [NSString stringWithFormat:@"Row %d", indexPath.row]; 109 | 110 | return cell; 111 | } 112 | 113 | /* 114 | // Override to support conditional editing of the table view. 115 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath 116 | { 117 | // Return NO if you do not want the specified item to be editable. 118 | return YES; 119 | } 120 | */ 121 | 122 | /* 123 | // Override to support editing the table view. 124 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 125 | { 126 | if (editingStyle == UITableViewCellEditingStyleDelete) { 127 | // Delete the row from the data source 128 | [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; 129 | } 130 | else if (editingStyle == UITableViewCellEditingStyleInsert) { 131 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view 132 | } 133 | } 134 | */ 135 | 136 | /* 137 | // Override to support rearranging the table view. 138 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath 139 | { 140 | } 141 | */ 142 | 143 | /* 144 | // Override to support conditional rearranging of the table view. 145 | - (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath 146 | { 147 | // Return NO if you do not want the item to be re-orderable. 148 | return YES; 149 | } 150 | */ 151 | 152 | #pragma mark - Table view delegate 153 | 154 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 155 | { 156 | 157 | // Get reference to the selected cell 158 | UITableViewCell *selectedCell = [tableView cellForRowAtIndexPath:indexPath]; 159 | 160 | // Get the detail from the selected cell 161 | NSString *theDetail = selectedCell.textLabel.text; 162 | 163 | // Call the delegate method to update the detail view controller, 164 | // passing in the detail from the selected cell 165 | [delegate updateDetailViewWith:theDetail]; 166 | 167 | } 168 | 169 | 170 | 171 | @end 172 | -------------------------------------------------------------------------------- /Chapter11/SplitViewApp/SplitViewApp/LeftTableViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 800 5 | 10C540 6 | 759 7 | 1038.25 8 | 458.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 77 12 | 13 | 14 | 15 | 16 | 17 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 18 | 19 | 20 | 21 | 22 | IBFilesOwner 23 | IBIPadFramework 24 | 25 | 26 | IBFirstResponder 27 | IBIPadFramework 28 | 29 | 30 | 31 | 274 32 | {768, 1024} 33 | 34 | 35 | 3 36 | MQA 37 | 38 | NO 39 | YES 40 | NO 41 | IBIPadFramework 42 | NO 43 | 1 44 | 0 45 | YES 46 | 44 47 | 22 48 | 22 49 | 50 | 51 | 52 | 53 | 54 | 55 | dataSource 56 | 57 | 58 | 59 | 9 60 | 61 | 62 | 63 | delegate 64 | 65 | 66 | 67 | 10 68 | 69 | 70 | 71 | view 72 | 73 | 74 | 75 | 11 76 | 77 | 78 | 79 | 80 | 81 | 0 82 | 83 | 84 | 85 | 86 | 87 | -1 88 | 89 | 90 | File's Owner 91 | 92 | 93 | -2 94 | 95 | 96 | 97 | 98 | 8 99 | 100 | 101 | 102 | 103 | 104 | 105 | LeftTableViewController 106 | UIResponder 107 | {{45, 132}, {768, 1024}} 108 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 109 | 110 | 111 | 112 | 113 | 114 | 11 115 | 116 | 117 | 118 | 119 | LeftTableViewController 120 | UIViewController 121 | 122 | IBProjectSource 123 | LeftTableViewController.h 124 | 125 | 126 | 127 | 128 | 0 129 | IBIPadFramework 130 | YES 131 | 132 | 3 133 | 77 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /Chapter11/SplitViewApp/SplitViewApp/License.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Tim Duckett / Charismatic Megafauna Ltd 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Chapter11/SplitViewApp/SplitViewApp/RightDetailViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // RightDetailViewController.h 3 | // SplitViewApp 4 | // 5 | // Created by Tim Duckett on 04/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "UpdateSplitDetailViewProtocol.h" 12 | 13 | @interface RightDetailViewController : UIViewController 14 | 15 | @property (nonatomic, strong) IBOutlet UILabel *statusLabel; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Chapter11/SplitViewApp/SplitViewApp/RightDetailViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // RightDetailViewController.m 3 | // SplitViewApp 4 | // 5 | // Created by Tim Duckett on 04/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import "RightDetailViewController.h" 10 | 11 | @implementation RightDetailViewController 12 | 13 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 14 | { 15 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 16 | if (self) { 17 | // Custom initialization 18 | } 19 | return self; 20 | } 21 | 22 | - (void)didReceiveMemoryWarning 23 | { 24 | // Releases the view if it doesn't have a superview. 25 | [super didReceiveMemoryWarning]; 26 | 27 | // Release any cached data, images, etc that aren't in use. 28 | } 29 | 30 | #pragma mark - View lifecycle 31 | 32 | - (void)viewDidLoad 33 | { 34 | [super viewDidLoad]; 35 | // Do any additional setup after loading the view from its nib. 36 | } 37 | 38 | - (void)viewDidUnload 39 | { 40 | [super viewDidUnload]; 41 | // Release any retained subviews of the main view. 42 | // e.g. self.myOutlet = nil; 43 | self.statusLabel = nil; 44 | } 45 | 46 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 47 | { 48 | // Return YES for supported orientations 49 | return YES; 50 | } 51 | 52 | 53 | #pragma mark - 54 | #pragma mark UISplitViewControllerDelegate 55 | 56 | -(void)splitViewController:(UISplitViewController *)svc willHideViewController:(UIViewController *)aViewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)pc { 57 | 58 | // Set up the bar button when the list view disappears 59 | [barButtonItem setTitle:@"Show list"]; 60 | self.navigationItem.leftBarButtonItem = barButtonItem; 61 | } 62 | 63 | -(void)splitViewController:(UISplitViewController *)svc willShowViewController:(UIViewController *)aViewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem { 64 | 65 | // Hide the bar button when the list view reappears 66 | self.navigationItem.leftBarButtonItem = nil; 67 | 68 | } 69 | 70 | #pragma mark - 71 | #pragma mark UpdateSplitDetailViewProtocol 72 | 73 | -(void)updateDetailViewWith:(NSString *)detail { 74 | 75 | // Respond to the delegate method being called 76 | 77 | NSLog(@"updateDetailViewWith:%@ called", detail); 78 | 79 | self.statusLabel.text = [NSString stringWithFormat:@"%@ was selected", detail]; 80 | 81 | } 82 | 83 | @end 84 | 85 | 86 | -------------------------------------------------------------------------------- /Chapter11/SplitViewApp/SplitViewApp/SVAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // SVAppDelegate.h 3 | // SplitViewApp 4 | // 5 | // Created by Tim Duckett on 04/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class SplitViewController; 12 | 13 | @interface SVAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | @property (strong, nonatomic) UISplitViewController *splitViewController; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Chapter11/SplitViewApp/SplitViewApp/SVAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // SVAppDelegate.m 3 | // SplitViewApp 4 | // 5 | // Created by Tim Duckett on 04/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import "SVAppDelegate.h" 10 | 11 | #import "LeftTableViewController.h" 12 | #import "RightDetailViewController.h" 13 | 14 | @implementation SVAppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 19 | // Override point for customization after application launch. 20 | 21 | // Create left view controller 22 | LeftTableViewController *leftTableVC = [[LeftTableViewController alloc] initWithNibName:@"LeftTableViewController" bundle:nil]; 23 | UINavigationController *leftNavController = [[UINavigationController alloc] initWithRootViewController:leftTableVC]; 24 | 25 | // Create right view controlller 26 | RightDetailViewController *rightDetailVC = [[RightDetailViewController alloc] initWithNibName:@"RightDetailViewController" bundle:nil]; 27 | UINavigationController *rightNavController = [[UINavigationController alloc] initWithRootViewController:rightDetailVC]; 28 | 29 | // Set left view controller's delegate 30 | leftTableVC.delegate = rightDetailVC; 31 | 32 | // Create split view controller and load its view controllers 33 | self.splitViewController = [[UISplitViewController alloc] init]; 34 | NSArray *viewControllers = [[NSArray alloc] initWithObjects:leftNavController, rightNavController, nil]; 35 | 36 | self.splitViewController.delegate = rightDetailVC; 37 | self.splitViewController.viewControllers = viewControllers; 38 | 39 | // Add the split view controller to the view 40 | // Deprecated in iOS6 41 | //[self.window addSubview:_splitViewController.view]; 42 | 43 | // For iOS6, add the split view controller as the root view controller 44 | self.window.rootViewController = self.splitViewController; 45 | 46 | // Set up the window and return 47 | [self.window makeKeyAndVisible]; 48 | return YES; 49 | } 50 | 51 | - (void)applicationWillResignActive:(UIApplication *)application 52 | { 53 | /* 54 | Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 55 | Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 56 | */ 57 | } 58 | 59 | - (void)applicationDidEnterBackground:(UIApplication *)application 60 | { 61 | /* 62 | Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 63 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 64 | */ 65 | } 66 | 67 | - (void)applicationWillEnterForeground:(UIApplication *)application 68 | { 69 | /* 70 | Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 71 | */ 72 | } 73 | 74 | - (void)applicationDidBecomeActive:(UIApplication *)application 75 | { 76 | /* 77 | Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 78 | */ 79 | } 80 | 81 | - (void)applicationWillTerminate:(UIApplication *)application 82 | { 83 | /* 84 | Called when the application is about to terminate. 85 | Save data if appropriate. 86 | See also applicationDidEnterBackground:. 87 | */ 88 | } 89 | 90 | @end 91 | -------------------------------------------------------------------------------- /Chapter11/SplitViewApp/SplitViewApp/SplitViewApp-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFiles 12 | 13 | CFBundleIdentifier 14 | uk.co.charismaticmegafauna.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations~ipad 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeRight 37 | UIInterfaceOrientationLandscapeLeft 38 | UIInterfaceOrientationPortraitUpsideDown 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /Chapter11/SplitViewApp/SplitViewApp/SplitViewApp-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'SplitViewApp' target in the 'SplitViewApp' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /Chapter11/SplitViewApp/SplitViewApp/UpdateSplitDetailViewProtocol.h: -------------------------------------------------------------------------------- 1 | // 2 | // UpdateSplitDetailViewProtocol.h 3 | // SplitViewApp 4 | // 5 | // Created by Tim Duckett on 04/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol UpdateSplitDetailViewProtocol 12 | 13 | -(void)updateDetailViewWith:(NSString *)detail; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Chapter11/SplitViewApp/SplitViewApp/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Chapter11/SplitViewApp/SplitViewApp/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SplitViewApp 4 | // 5 | // Created by Tim Duckett on 04/01/2012. 6 | // Copyright (c) 2012 Charismatic Megafauna Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "SVAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SVAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | Source code for Pro iOS Table Views: for iPhone, iPad and iPod Touch 2 | ==================================================================== 3 | This project contains the source code from *Pro iOS Table Views*, published by Apress. 4 | 5 | It's divided by chapter, and contains the source code for the projects referenced in the text. 6 | 7 | To clone the source code en-masse, use 8 | `git clone git@github.com:timd/Pro-iOS-TableViews.git` 9 | 10 | Notes 11 | ----- 12 | The code was written using Xcode 4.2, and compiled against iOS5. It's been tested on an iPhone 4 and iPad 2. All projects use ARC. 13 | 14 | The book 15 | -------- 16 | *Pro iOS Table Views: for iPhone, iPad and iPod Touch* is published by Apress, Inc. 17 | 18 | ISBN-13: 978-0-4302-3348-0 (print) 19 | 20 | ISBN-13: 978-1-4302-3349-7 (eBook) 21 | 22 | It's available from Amazon and other sources: 23 | 24 | (US) [http://www.amazon.com/Pro-iOS-Table-Views-iPhone/dp/1430233486/](http://www.amazon.com/Pro-iOS-Table-Views-iPhone/dp/1430233486/) 25 | 26 | (UK) [http://www.amazon.co.uk/Pro-iOS-Table-Views-iPhone/dp/1430233486/](http://www.amazon.co.uk/Pro-iOS-Table-Views-iPhone/dp/1430233486/) 27 | 28 | Book Abstract: 29 | -------------- 30 | 31 | If you’re an iOS app developer, chances are you’ll be using table views in your development projects. Table views are the bread and butter of iOS apps. With them, you can create everything from the simplest of lists to fully tricked-out user interfaces. 32 | 33 | Table views are one of the most complex components found in UIKit. While using them for boring standard user interfaces is quite simple, customizing them can become really challenging. 34 | Pro iOS Table Views takes a task-oriented focus to assist you when implementing customized table views. Although it delves deeply into the Table View API, you can always decide in which level of detail you want to dive in. It’s aimed to be a great reference and customization cookbook at the same time, useful for beginners as well as intermediate developers. 35 | 36 | * Covers the entire Table View API in depth 37 | * Covers customization and performance topics in depth 38 | * Task-oriented reference with multiple levels of detail 39 | 40 | *What you’ll learn* 41 | 42 | * The anatomy of tables and cells 43 | * The design patterns that power the table view 44 | * How to create and configure table views 45 | * How to customize every last little detail of the table view 46 | * How to use table views on the iPad 47 | * Advanced tips and tricks for performance and killer user interfaces 48 | * The latest updates in iOS 5 and how to exploit them 49 | 50 | *Who this book is for* 51 | 52 | The book is targeted at iOS developers who need to customize Table Views. The information is divided into several layers of detail. While the book covers complex customization topics and user interaction techniques, it provides the fundamental basics needed for customization. Both beginners and intermediate developers will find great value in this book as a helpful reference, at hand to quickly refresh their knowledge at any given time. 53 | 54 | Code license 55 | ============ 56 | This code is licensed under the MIT License. See License.txt in each project for details. 57 | --------------------------------------------------------------------------------