├── Example ├── Images.xcassets │ ├── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── AppDelegate.m ├── Classes │ ├── ViewController.h │ ├── TableDataSource.h │ ├── ViewController.m │ └── TableDataSource.m ├── AppDelegate.h ├── Supporting Files │ ├── main.m │ └── Info.plist └── Storyboards │ ├── LaunchScreen.xib │ └── Main.storyboard ├── Example.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcshareddata │ └── xcschemes │ │ └── Example.xcscheme └── project.pbxproj ├── PickerCells ├── PickerCells.h ├── PickerCellsDelegate.h ├── PickerCellsController.h └── PickerCellsController.m ├── .gitignore ├── PickerCells.podspec ├── LICENSE └── README.md /Example/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Example.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PickerCells/PickerCells.h: -------------------------------------------------------------------------------- 1 | // 2 | // PickerCells.h 3 | // Example 4 | // 5 | // Created by Danis Ziganshin on 21/07/15. 6 | // Copyright (c) 2015 Danis Ziganshin. All rights reserved. 7 | // 8 | 9 | #import "PickerCellsController.h" 10 | #import "PickerCellsDelegate.h" -------------------------------------------------------------------------------- /Example/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // PickerCells 4 | // 5 | // Created by Danis Ziganshin on 21/07/15. 6 | // Copyright (c) 2015 Danis Ziganshin. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | .DS_Store -------------------------------------------------------------------------------- /Example/Classes/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // PickerCells 4 | // 5 | // Created by Danis Ziganshin on 21/07/15. 6 | // Copyright (c) 2015 Danis Ziganshin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UITableViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Example/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // PickerCells 4 | // 5 | // Created by Danis Ziganshin on 21/07/15. 6 | // Copyright (c) 2015 Danis Ziganshin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /Example/Supporting Files/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PickerCells 4 | // 5 | // Created by Danis Ziganshin on 21/07/15. 6 | // Copyright (c) 2015 Danis Ziganshin. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Example/Classes/TableDataSource.h: -------------------------------------------------------------------------------- 1 | // 2 | // TableDataSource.h 3 | // PickerCells 4 | // 5 | // Created by Danis Ziganshin on 21/07/15. 6 | // Copyright (c) 2015 Danis Ziganshin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface TableDataSource : NSObject 12 | 13 | - (instancetype)initWthTable:(UITableView *)tableView; 14 | 15 | - (void)disableFirstPicker; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /PickerCells/PickerCellsDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // PickerCellsDelegate.h 3 | // Example 4 | // 5 | // Created by Danis Ziganshin on 21/07/15. 6 | // Copyright (c) 2015 Danis Ziganshin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class PickerCellsController; 12 | @protocol PickerCellsDelegate 13 | 14 | @optional 15 | - (void)pickerCellsController:(PickerCellsController *)controller willExpandTableViewContent:(UITableView *)tableView forHeight:(CGFloat)expandHeight; 16 | - (void)pickerCellsController:(PickerCellsController *)controller willCollapseTableViewContent:(UITableView *)tableView forHeight:(CGFloat)expandHeight; 17 | 18 | @end -------------------------------------------------------------------------------- /Example/Classes/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // PickerCells 4 | // 5 | // Created by Danis Ziganshin on 21/07/15. 6 | // Copyright (c) 2015 Danis Ziganshin. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "TableDataSource.h" 11 | 12 | @interface ViewController () 13 | 14 | @property (nonatomic, strong) TableDataSource *dataSource; 15 | 16 | @end 17 | 18 | @implementation ViewController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | self.dataSource = [[TableDataSource alloc] initWthTable:self.tableView]; 23 | self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Disable 1st" style:UIBarButtonItemStylePlain target:self.dataSource action:@selector(disableFirstPicker)]; 24 | } 25 | 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /PickerCells.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "PickerCells" 3 | s.version = "1.1.0" 4 | s.summary = "UIDatePicker or UIPickerView that will slide in/out by tapping on the cell in your UITableView" 5 | s.description = <<-DESC 6 | This class adds UIDatePicker or UIPickerView that will slide in/out by tapping on the cell in your UITableView. 7 | Inspired by Apple's DateCell example and andjash's DateCellsController. 8 | DESC 9 | s.homepage = "https://github.com/zigdanis/PickerCells" 10 | s.screenshots = "http://i.imgur.com/Z8vbhNFl.png", "http://i.imgur.com/WfgTUtel.png" 11 | s.license = 'MIT' 12 | s.author = { "Danis Ziganshin" => "zigdanis@gmail.com" } 13 | s.source = { :git => "https://github.com/zigdanis/PickerCells.git", :tag => s.version.to_s } 14 | s.platform = :ios, '6.0' 15 | s.requires_arc = true 16 | s.source_files = 'PickerCells' 17 | end -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Danis Ziganshin 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Example/Supporting Files/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | DZ.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 2 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Example/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "8.0", 8 | "subtype" : "736h", 9 | "scale" : "3x" 10 | }, 11 | { 12 | "orientation" : "portrait", 13 | "idiom" : "iphone", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "8.0", 16 | "subtype" : "667h", 17 | "scale" : "2x" 18 | }, 19 | { 20 | "orientation" : "portrait", 21 | "idiom" : "iphone", 22 | "extent" : "full-screen", 23 | "minimum-system-version" : "7.0", 24 | "scale" : "2x" 25 | }, 26 | { 27 | "orientation" : "portrait", 28 | "idiom" : "iphone", 29 | "extent" : "full-screen", 30 | "minimum-system-version" : "7.0", 31 | "subtype" : "retina4", 32 | "scale" : "2x" 33 | }, 34 | { 35 | "orientation" : "portrait", 36 | "idiom" : "iphone", 37 | "extent" : "full-screen", 38 | "scale" : "1x" 39 | }, 40 | { 41 | "orientation" : "portrait", 42 | "idiom" : "iphone", 43 | "extent" : "full-screen", 44 | "scale" : "2x" 45 | }, 46 | { 47 | "orientation" : "portrait", 48 | "idiom" : "iphone", 49 | "extent" : "full-screen", 50 | "subtype" : "retina4", 51 | "scale" : "2x" 52 | } 53 | ], 54 | "info" : { 55 | "version" : 1, 56 | "author" : "xcode" 57 | } 58 | } -------------------------------------------------------------------------------- /PickerCells/PickerCellsController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PickerCellsController.h 3 | // Example 4 | // 5 | // Created by Danis Ziganshin on 21/07/15. 6 | // Copyright (c) 2015 Danis Ziganshin. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @protocol PickerCellsDelegate; 12 | 13 | @interface PickerCellsController : NSObject 14 | 15 | /* This method attaching PickerCellController to your `tableView`. 16 | PickerCellsController then will propogate UITableViewDataSource and UITableViewDelegate calls to your `priorDelegate` object. 17 | Also you can provide your PickerCellsDelegate object in order to receive willExpand and willCollapse callbacks. 18 | */ 19 | - (void)attachToTableView:(UITableView *)tableView tableViewsPriorDelegate:(id )priorDelegate withDelegate:(id)delegate; 20 | 21 | /* Use this method to setup PickerCellsController with `datePicker` that will be shown when user tapping on specified `indexPath` 22 | */ 23 | - (void)addDatePicker:(UIDatePicker *)datePicker forIndexPath:(NSIndexPath *)indexPath; 24 | 25 | /* Use this method to setup PickerCellsController with `pickerView` that will be shown when user tapping on specified `indexPath` 26 | */ 27 | - (void)addPickerView:(UIPickerView *)pickerView forIndexPath:(NSIndexPath *)indexPath; 28 | 29 | /* You can remove previously added picker from the specified indexPath to prevent it's expanding by user's tap. 30 | */ 31 | - (void)removePickerAtIndexPath:(NSIndexPath *)indexPath; 32 | 33 | /* Use this method to hide currently shown picker programmatically. Notice that only 1 picker can be shown at a time. 34 | */ 35 | - (void)hidePicker; 36 | 37 | /* This method can be used to retrieve `picker` that were previously attached to the `indexPath` with -addDatePicker:forIndexPath: or -addPickerView:forIndexPath 38 | */ 39 | - (id)pickerForOwnerCellIndexPath:(NSIndexPath *)indexPath; 40 | 41 | /* This methid can be used to retrieve 'indexPath' that were previously attached to the `picker` with -addDatePicker:forIndexPath: or -addPickerView:forIndexPath 42 | */ 43 | - (NSIndexPath *)indexPathForPicker:(id)picker; 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PickerCells 2 | This class adds UIDatePicker or UIPickerView that will expand or collapse by tapping on the cell in your UITableView. 3 | 4 | Inspired by Apple's [DateCell](https://developer.apple.com/library/ios/samplecode/DateCell/Introduction/Intro.html) example and [andjash's](https://github.com/andjash) [DateCellsController](https://github.com/andjash/DateCellsController). 5 | 6 | ## Screenshots 7 | 8 | 9 | ## Minimum iOS version 10 | iOS 6.0 11 | ## Usage 12 | 1. Import with `#import "PickerCells.h"` 13 | 2. Instantiate and setup `PickerCellsController` class. 14 | 15 | ```objective-c 16 | self.pickersController = [[PickerCellsController alloc] init]; 17 | [self.pickersController attachToTableView:self.tableView tableViewsPriorDelegate:self withDelegate:self]; 18 | ``` 19 | 3. Add `UIPickerView` and `UIDatePicker` instances with correspoding indexPaths 20 | 21 | ```objective-c 22 | UIPickerView *pickerView = [[UIPickerView alloc] init]; 23 | pickerView.delegate = self; 24 | pickerView.dataSource = self; 25 | NSIndexPath *pickerIP = [NSIndexPath indexPathForRow:1 inSection:1]; 26 | [self.pickersController addPickerView:pickerView forIndexPath:pickerIP]; 27 | 28 | UIDatePicker *datePicker1 = [[UIDatePicker alloc] init]; 29 | datePicker1.datePickerMode = UIDatePickerModeDate; 30 | datePicker1.date = [NSDate date]; 31 | NSIndexPath *path1 = [NSIndexPath indexPathForRow:2 inSection:0]; 32 | [self.pickersController addDatePicker:datePicker1 forIndexPath:path1]; 33 | ``` 34 | 4. Check it out! Try pressing cells on specified indexPath's to see how pickers will expand underneath them. 35 | 5. This class do not responsible for giving you information about picker selected values. You should do it by yourself. But you can get pickers from `PickerCellsController` object by using corresponding cells indexPaths: 36 | 37 | ```objective-c 38 | id picker = [self.pickersController pickerForOwnerCellIndexPath:indexPath]; 39 | if ([picker isKindOfClass:UIDatePicker.class]) { 40 | UIDatePicker *datePicker = (UIDatePicker *)picker; 41 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 42 | [dateFormatter setDateFormat:@"dd-MM-yyyy"]; 43 | cell.textLabel.text = [dateFormatter stringFromDate:[datePicker date]]; 44 | } 45 | ``` 46 | 47 | ## Installation 48 | 49 | ```sh 50 | pod 'PickerCells' 51 | ``` 52 | 53 | ## License 54 | MIT 55 | -------------------------------------------------------------------------------- /Example/Storyboards/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 21 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /Example.xcodeproj/xcshareddata/xcschemes/Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 69 | 70 | 71 | 72 | 73 | 74 | 80 | 82 | 88 | 89 | 90 | 91 | 93 | 94 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /Example/Storyboards/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /Example/Classes/TableDataSource.m: -------------------------------------------------------------------------------- 1 | // 2 | // TableDataSource.m 3 | // PickerCells 4 | // 5 | // Created by Danis Ziganshin on 21/07/15. 6 | // Copyright (c) 2015 Danis Ziganshin. All rights reserved. 7 | // 8 | 9 | #import "TableDataSource.h" 10 | #import "PickerCells.h" 11 | 12 | @interface TableDataSource () 13 | 14 | @property (nonatomic, weak) UITableView *tableView; 15 | @property (nonatomic, strong) PickerCellsController *pickersController; 16 | 17 | @end 18 | 19 | @implementation TableDataSource 20 | 21 | - (instancetype)initWthTable:(UITableView *)tableView { 22 | if (self = [super init]) { 23 | self.tableView = tableView; 24 | tableView.delegate = self; 25 | tableView.dataSource = self; 26 | [self setupTableWithPickers]; 27 | } 28 | return self; 29 | } 30 | 31 | - (void)disableFirstPicker { 32 | [self.pickersController removePickerAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 33 | } 34 | 35 | - (void)setupTableWithPickers { 36 | self.pickersController = [[PickerCellsController alloc] init]; 37 | [self.pickersController attachToTableView:self.tableView tableViewsPriorDelegate:self withDelegate:self]; 38 | 39 | UIPickerView *pickerView = [[UIPickerView alloc] init]; 40 | pickerView.delegate = self; 41 | pickerView.dataSource = self; 42 | NSIndexPath *pickerIP = [NSIndexPath indexPathForRow:1 inSection:1]; 43 | [self.pickersController addPickerView:pickerView forIndexPath:pickerIP]; 44 | 45 | UIDatePicker *datePicker1 = [[UIDatePicker alloc] init]; 46 | datePicker1.datePickerMode = UIDatePickerModeDate; 47 | datePicker1.date = [NSDate date]; 48 | NSIndexPath *path1 = [NSIndexPath indexPathForRow:2 inSection:0]; 49 | [self.pickersController addDatePicker:datePicker1 forIndexPath:path1]; 50 | 51 | UIDatePicker *datePicker2 = [[UIDatePicker alloc] init]; 52 | datePicker2.datePickerMode = UIDatePickerModeDateAndTime; 53 | datePicker2.date = [NSDate dateWithTimeIntervalSinceNow:5000]; 54 | NSIndexPath *path2 = [NSIndexPath indexPathForRow:0 inSection:0]; 55 | [self.pickersController addDatePicker:datePicker2 forIndexPath:path2]; 56 | 57 | UIDatePicker *datePicker3 = [[UIDatePicker alloc] init]; 58 | datePicker3.datePickerMode = UIDatePickerModeTime; 59 | datePicker3.date = [NSDate dateWithTimeIntervalSinceNow:5000]; 60 | NSIndexPath *path3 = [NSIndexPath indexPathForRow:0 inSection:1]; 61 | [self.pickersController addDatePicker:datePicker3 forIndexPath:path3]; 62 | 63 | [datePicker1 addTarget:self action:@selector(dateSelected:) forControlEvents:UIControlEventValueChanged]; 64 | [datePicker2 addTarget:self action:@selector(dateSelected:) forControlEvents:UIControlEventValueChanged]; 65 | [datePicker3 addTarget:self action:@selector(dateSelected:) forControlEvents:UIControlEventValueChanged]; 66 | 67 | } 68 | 69 | #pragma mark - UITableView DataSOurce / Delegate 70 | 71 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 72 | return 2; 73 | } 74 | 75 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 76 | return 6; 77 | } 78 | 79 | - (UITableViewCell *)tableView:(UITableView *)tableViewInner cellForRowAtIndexPath:(NSIndexPath *)indexPath { 80 | 81 | static NSString *cellReuseId = @"id"; 82 | 83 | UITableViewCell *cell = [tableViewInner dequeueReusableCellWithIdentifier:cellReuseId]; 84 | if (!cell) { 85 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellReuseId]; 86 | } 87 | 88 | id picker = [self.pickersController pickerForOwnerCellIndexPath:indexPath]; 89 | if (picker) { 90 | cell.textLabel.textColor = [UIColor blueColor]; 91 | if ([picker isKindOfClass:UIPickerView.class]) { 92 | UIPickerView *pickerView = (UIPickerView *)picker; 93 | NSInteger selectedRow = [pickerView selectedRowInComponent:0]; 94 | NSString *title = [self pickerView:pickerView titleForRow:selectedRow forComponent:0]; 95 | cell.textLabel.text = title; 96 | } else if ([picker isKindOfClass:UIDatePicker.class]) { 97 | UIDatePicker *datePicker = (UIDatePicker *)picker; 98 | NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; 99 | if (datePicker.datePickerMode == UIDatePickerModeDate) { 100 | [dateFormatter setDateFormat:@"dd-MM-yyyy"]; 101 | } else if (datePicker.datePickerMode == UIDatePickerModeDateAndTime) { 102 | [dateFormatter setDateFormat:@"dd-MM-yyyy:HH-mm"]; 103 | } else { 104 | [dateFormatter setDateFormat:@"HH-mm"]; 105 | } 106 | cell.textLabel.text = [dateFormatter stringFromDate:[(UIDatePicker *)picker date]]; 107 | } 108 | } else { 109 | cell.textLabel.textColor = [UIColor lightGrayColor]; 110 | cell.textLabel.text = [NSString stringWithFormat:@"Section: %ld row: %ld", (long)indexPath.section, (long)indexPath.row]; 111 | } 112 | return cell; 113 | 114 | } 115 | 116 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 117 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 118 | } 119 | 120 | #pragma mark - UIPickerView DataSource 121 | 122 | - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView { 123 | return 1; 124 | } 125 | 126 | - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component { 127 | return 30; 128 | } 129 | 130 | - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component { 131 | NSString *text = [NSString stringWithFormat:@"Selected number %li", (long)row]; 132 | return text; 133 | } 134 | 135 | - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component { 136 | NSIndexPath *ip = [self.pickersController indexPathForPicker:pickerView]; 137 | if (ip) { 138 | [self.tableView reloadRowsAtIndexPaths:@[ip] withRowAnimation:UITableViewRowAnimationAutomatic]; 139 | } 140 | } 141 | 142 | #pragma mark - PickerCellsDelegate 143 | 144 | - (void)pickerCellsController:(PickerCellsController *)controller willExpandTableViewContent:(UITableView *)tableView forHeight:(CGFloat)expandHeight { 145 | NSLog(@"expand height = %.f", expandHeight); 146 | } 147 | 148 | - (void)pickerCellsController:(PickerCellsController *)controller willCollapseTableViewContent:(UITableView *)tableView forHeight:(CGFloat)expandHeight { 149 | NSLog(@"collapse height = %.f", expandHeight); 150 | } 151 | 152 | #pragma mark - Actions 153 | 154 | - (void)dateSelected:(UIDatePicker *)sender { 155 | NSIndexPath *ip = [self.pickersController indexPathForPicker:sender]; 156 | if (ip) { 157 | [self.tableView reloadRowsAtIndexPaths:@[ip] withRowAnimation:UITableViewRowAnimationAutomatic]; 158 | } 159 | } 160 | 161 | 162 | @end 163 | -------------------------------------------------------------------------------- /PickerCells/PickerCellsController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PickerCellsController.m 3 | // Example 4 | // 5 | // Created by Danis Ziganshin on 21/07/15. 6 | // Copyright (c) 2015 Danis Ziganshin. All rights reserved. 7 | // 8 | 9 | #import "PickerCellsController.h" 10 | #import "PickerCellsDelegate.h" 11 | 12 | #define kDefaultRowHeight 44 13 | #define PickerCellIdentifier @"PickerCell" 14 | #define kPickerTag 31 15 | 16 | @interface PickerCellsController () 17 | 18 | @property (nonatomic, weak) id priorDelegate; 19 | @property (nonatomic, weak) id delegate; 20 | @property (nonatomic, strong) UITableView *tableView; 21 | @property (nonatomic, strong) NSIndexPath *pickerIndexPath; 22 | @property (nonatomic, strong) NSMutableDictionary *cellsWithPickersByIndexPaths; 23 | 24 | @end 25 | 26 | @implementation PickerCellsController 27 | 28 | #pragma mark - Life Cycle 29 | 30 | - (instancetype)init { 31 | if (self = [super init]) { 32 | self.cellsWithPickersByIndexPaths = [NSMutableDictionary dictionary]; 33 | } 34 | return self; 35 | } 36 | 37 | #pragma mark - Propetries 38 | 39 | - (void)setTableView:(UITableView *)tableView { 40 | _tableView = tableView; 41 | _tableView.delegate = self; 42 | _tableView.dataSource = self; 43 | } 44 | 45 | #pragma mark - Public 46 | 47 | - (void)attachToTableView:(UITableView *)tableView tableViewsPriorDelegate:(id )priorDelegate withDelegate:(id)delegate { 48 | self.priorDelegate = priorDelegate; 49 | self.tableView = tableView; 50 | self.delegate = delegate; 51 | } 52 | 53 | - (void)addPickerView:(UIPickerView *)pickerView forIndexPath:(NSIndexPath *)indexPath { 54 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:PickerCellIdentifier]; 55 | pickerView.translatesAutoresizingMaskIntoConstraints = NO; 56 | pickerView.tag = kPickerTag; 57 | [cell.contentView addSubview:pickerView]; 58 | NSDictionary *viewsDict = NSDictionaryOfVariableBindings(pickerView); 59 | [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[pickerView]-|" options:0 metrics:nil views:viewsDict]]; 60 | [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[pickerView]-|" options:0 metrics:nil views:viewsDict]]; 61 | [self.cellsWithPickersByIndexPaths setObject:cell forKey:indexPath]; 62 | } 63 | 64 | - (void)addDatePicker:(UIDatePicker *)datePicker forIndexPath:(NSIndexPath *)indexPath { 65 | UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:PickerCellIdentifier]; 66 | datePicker.translatesAutoresizingMaskIntoConstraints = NO; 67 | datePicker.tag = kPickerTag; 68 | [cell.contentView addSubview:datePicker]; 69 | NSDictionary *viewsDict = NSDictionaryOfVariableBindings(datePicker); 70 | [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[datePicker]-|" options:0 metrics:nil views:viewsDict]]; 71 | [cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[datePicker]-|" options:0 metrics:nil views:viewsDict]]; 72 | [self.cellsWithPickersByIndexPaths setObject:cell forKey:indexPath]; 73 | } 74 | 75 | - (void)removePickerAtIndexPath:(NSIndexPath *)indexPath { 76 | NSIndexPath *nextIndexPath = [NSIndexPath indexPathForRow:indexPath.row + 1 inSection:indexPath.section]; 77 | if (self.pickerIndexPath == nextIndexPath) { 78 | [self hidePicker]; 79 | } 80 | [self.cellsWithPickersByIndexPaths removeObjectForKey:indexPath]; 81 | } 82 | 83 | - (void)hidePicker { 84 | if (self.pickerIndexPath) { 85 | NSIndexPath *dateCellPath = [NSIndexPath indexPathForRow:_pickerIndexPath.row - 1 inSection:_pickerIndexPath.section]; 86 | [self displayInlineDatePickerForRowAtIndexPath:dateCellPath]; 87 | } 88 | } 89 | 90 | - (id)pickerForOwnerCellIndexPath:(NSIndexPath *)indexPath { 91 | UITableViewCell *cell = [self.cellsWithPickersByIndexPaths objectForKey:indexPath]; 92 | id picker = [cell viewWithTag:kPickerTag]; 93 | return picker; 94 | } 95 | 96 | - (NSIndexPath *)indexPathForPicker:(id)picker { 97 | for (NSIndexPath *key in self.cellsWithPickersByIndexPaths) { 98 | UITableViewCell *cell = [self.cellsWithPickersByIndexPaths objectForKey:key]; 99 | id cellPicker = [cell viewWithTag:kPickerTag]; 100 | if (cellPicker == picker) { 101 | return key; 102 | } 103 | } 104 | return nil; 105 | } 106 | 107 | #pragma mark - Private 108 | 109 | - (void)displayInlineDatePickerForRowAtIndexPath:(NSIndexPath *)indexPath { 110 | [self.tableView beginUpdates]; 111 | 112 | BOOL before = NO; 113 | BOOL sameCellClicked = ([self hasInlineDatePicker] && self.pickerIndexPath.row - 1 == indexPath.row) 114 | && self.pickerIndexPath.section == indexPath.section; 115 | 116 | if ([self hasInlineDatePicker]) { 117 | if (self.pickerIndexPath.row < indexPath.row && 118 | self.pickerIndexPath.section == indexPath.section) { 119 | before = YES; 120 | } 121 | [self.tableView deleteRowsAtIndexPaths:@[self.pickerIndexPath] withRowAnimation:UITableViewRowAnimationFade]; 122 | self.pickerIndexPath = nil; 123 | } else { 124 | if ([self.delegate respondsToSelector:@selector(pickerCellsController:willExpandTableViewContent:forHeight:)]) { 125 | CGFloat height = [self calculatedHeightForSizingCell:[self.cellsWithPickersByIndexPaths objectForKey:indexPath]]; 126 | [self.delegate pickerCellsController:self willExpandTableViewContent:self.tableView forHeight:height]; 127 | } 128 | } 129 | 130 | if (!sameCellClicked) { 131 | NSInteger rowToReveal = (before ? indexPath.row - 1 : indexPath.row); 132 | NSIndexPath *indexPathToReveal = [NSIndexPath indexPathForRow:rowToReveal inSection:[indexPath section]]; 133 | [self toggleDatePickerForSelectedIndexPath:indexPathToReveal]; 134 | self.pickerIndexPath = [NSIndexPath indexPathForRow:indexPathToReveal.row + 1 inSection:[indexPath section]]; 135 | } else { 136 | if ([self.delegate respondsToSelector:@selector(pickerCellsController:willCollapseTableViewContent:forHeight:)]) { 137 | CGFloat height = [self calculatedHeightForSizingCell:[self.cellsWithPickersByIndexPaths objectForKey:indexPath]]; 138 | [self.delegate pickerCellsController:self willCollapseTableViewContent:self.tableView forHeight:height]; 139 | } 140 | } 141 | 142 | [self.tableView deselectRowAtIndexPath:indexPath animated:YES]; 143 | [self.tableView endUpdates]; 144 | } 145 | 146 | - (void)toggleDatePickerForSelectedIndexPath:(NSIndexPath *)indexPath { 147 | [self.tableView beginUpdates]; 148 | NSArray *indexPaths = @[[NSIndexPath indexPathForRow:indexPath.row + 1 inSection:[indexPath section]]]; 149 | [self.tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade]; 150 | [self.tableView endUpdates]; 151 | } 152 | 153 | - (BOOL)hasInlineDatePicker { 154 | return (self.pickerIndexPath != nil); 155 | } 156 | 157 | - (BOOL)indexPathHasPicker:(NSIndexPath *)indexPath { 158 | return ([self hasInlineDatePicker] && ([self.pickerIndexPath compare:indexPath] == NSOrderedSame)); 159 | } 160 | 161 | 162 | #pragma mark - UITableViewDataSource 163 | 164 | 165 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 166 | if ([self indexPathHasPicker:indexPath]) { 167 | return [self calculatedHeightForSizingCell:[self pickerCellForIndexPath:indexPath]]; 168 | } else { 169 | if ([self.priorDelegate respondsToSelector:@selector(tableView:heightForRowAtIndexPath:)]) { 170 | return [self.priorDelegate tableView:tableView heightForRowAtIndexPath:indexPath]; 171 | } 172 | } 173 | return kDefaultRowHeight; 174 | } 175 | 176 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 177 | NSInteger numberOfRows = [self.priorDelegate tableView:tableView numberOfRowsInSection:section]; 178 | if ([self hasInlineDatePicker] && self.pickerIndexPath.section == section) { 179 | numberOfRows++; 180 | } 181 | return numberOfRows; 182 | } 183 | 184 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 185 | UITableViewCell *cell = nil; 186 | if ([self indexPathHasPicker:indexPath]) { 187 | cell = [self pickerCellForIndexPath:indexPath]; 188 | } else { 189 | NSIndexPath *shiftedIndexPath = [self shiftedIndexPathForIndexPath:indexPath]; 190 | cell = [self.priorDelegate tableView:tableView cellForRowAtIndexPath:shiftedIndexPath]; 191 | } 192 | return cell; 193 | } 194 | 195 | #pragma mark - UITableViewDelegate 196 | 197 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 198 | if (self.pickerIndexPath == indexPath) { 199 | [tableView deselectRowAtIndexPath:indexPath animated:YES]; 200 | return; 201 | } 202 | NSIndexPath *shiftedIndexPath = [self shiftedIndexPathForIndexPath:indexPath]; 203 | 204 | if ([self.cellsWithPickersByIndexPaths objectForKey:shiftedIndexPath]) { 205 | [self displayInlineDatePickerForRowAtIndexPath:indexPath]; 206 | } 207 | 208 | if ([self.priorDelegate respondsToSelector:@selector(tableView:didSelectRowAtIndexPath:)]) { 209 | [self.priorDelegate tableView:tableView didSelectRowAtIndexPath:shiftedIndexPath]; 210 | } 211 | } 212 | 213 | #pragma mark - NSObject 214 | 215 | - (void)forwardInvocation:(NSInvocation *)anInvocation { 216 | if ([self.priorDelegate respondsToSelector:[anInvocation selector]]) { 217 | [anInvocation invokeWithTarget:self.priorDelegate]; 218 | } else { 219 | [super forwardInvocation:anInvocation]; 220 | } 221 | } 222 | 223 | - (BOOL)respondsToSelector:(SEL)aSelector { 224 | BOOL respond = [super respondsToSelector:aSelector] || [self.priorDelegate respondsToSelector:aSelector]; 225 | return respond; 226 | } 227 | 228 | #pragma mark - Helpers 229 | 230 | - (NSIndexPath *)shiftedIndexPathForIndexPath:(NSIndexPath *)indexPath { 231 | NSIndexPath *shiftedIndexPath = indexPath; 232 | if ([self hasInlineDatePicker] && self.pickerIndexPath.section == indexPath.section) { 233 | BOOL before = _pickerIndexPath.row < indexPath.row; 234 | int shift = before ? -1 : 0; 235 | shiftedIndexPath = [NSIndexPath indexPathForRow:indexPath.row + shift inSection:indexPath.section]; 236 | } 237 | return shiftedIndexPath; 238 | } 239 | 240 | - (UITableViewCell *)pickerCellForIndexPath:(NSIndexPath *)indexPath { 241 | NSAssert1(indexPath.row > 0, @"indexPath's row should be bigger than 0, indexPath row = %li", (long)indexPath.row); 242 | NSIndexPath *ownerCellIndexPath = [NSIndexPath indexPathForRow:indexPath.row-1 inSection:indexPath.section]; 243 | UITableViewCell *cell = [self.cellsWithPickersByIndexPaths objectForKey:ownerCellIndexPath]; 244 | NSAssert2(cell != nil, @"Cell should not be nil for indexPath row = %li, section = %li", (long)indexPath.row, (long)indexPath.section); 245 | return cell; 246 | } 247 | 248 | - (CGFloat)calculatedHeightForSizingCell:(UITableViewCell *)sizingCell { 249 | NSAssert1(sizingCell != nil, @"Sizing method should not be called for if cell == nil", nil); 250 | [sizingCell setNeedsLayout]; 251 | [sizingCell layoutIfNeeded]; 252 | CGSize size = [sizingCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; 253 | return size.height + 1.0f; // Add 1.0f for the cell separator height 254 | } 255 | 256 | @end 257 | -------------------------------------------------------------------------------- /Example.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 096D16F41B5E632D00CFB8F8 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 096D16E71B5E632D00CFB8F8 /* AppDelegate.m */; }; 11 | 096D16F51B5E632D00CFB8F8 /* TableDataSource.m in Sources */ = {isa = PBXBuildFile; fileRef = 096D16EA1B5E632D00CFB8F8 /* TableDataSource.m */; }; 12 | 096D16F61B5E632D00CFB8F8 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 096D16EC1B5E632D00CFB8F8 /* ViewController.m */; }; 13 | 096D16F81B5E632D00CFB8F8 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 096D16EF1B5E632D00CFB8F8 /* LaunchScreen.xib */; }; 14 | 096D16F91B5E632D00CFB8F8 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 096D16F01B5E632D00CFB8F8 /* Main.storyboard */; }; 15 | 096D16FB1B5E632D00CFB8F8 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 096D16F31B5E632D00CFB8F8 /* main.m */; }; 16 | 096D16FF1B5E643C00CFB8F8 /* PickerCellsController.m in Sources */ = {isa = PBXBuildFile; fileRef = 096D16FE1B5E643C00CFB8F8 /* PickerCellsController.m */; }; 17 | 099CEAC51C635C8900D2605B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 099CEAC41C635C8900D2605B /* Images.xcassets */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXFileReference section */ 21 | 096D16AB1B5E60AC00CFB8F8 /* Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; 22 | 096D16E61B5E632D00CFB8F8 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 23 | 096D16E71B5E632D00CFB8F8 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 24 | 096D16E91B5E632D00CFB8F8 /* TableDataSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TableDataSource.h; sourceTree = ""; }; 25 | 096D16EA1B5E632D00CFB8F8 /* TableDataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TableDataSource.m; sourceTree = ""; }; 26 | 096D16EB1B5E632D00CFB8F8 /* ViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 27 | 096D16EC1B5E632D00CFB8F8 /* ViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 28 | 096D16EF1B5E632D00CFB8F8 /* LaunchScreen.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = LaunchScreen.xib; sourceTree = ""; }; 29 | 096D16F01B5E632D00CFB8F8 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; 30 | 096D16F21B5E632D00CFB8F8 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 31 | 096D16F31B5E632D00CFB8F8 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 32 | 096D16FD1B5E643C00CFB8F8 /* PickerCellsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PickerCellsController.h; sourceTree = ""; }; 33 | 096D16FE1B5E643C00CFB8F8 /* PickerCellsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PickerCellsController.m; sourceTree = ""; }; 34 | 096D17001B5E644B00CFB8F8 /* PickerCells.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PickerCells.h; sourceTree = ""; }; 35 | 096D17011B5E653800CFB8F8 /* PickerCellsDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PickerCellsDelegate.h; sourceTree = ""; }; 36 | 099CEAC41C635C8900D2605B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 37 | /* End PBXFileReference section */ 38 | 39 | /* Begin PBXFrameworksBuildPhase section */ 40 | 096D16A81B5E60AC00CFB8F8 /* Frameworks */ = { 41 | isa = PBXFrameworksBuildPhase; 42 | buildActionMask = 2147483647; 43 | files = ( 44 | ); 45 | runOnlyForDeploymentPostprocessing = 0; 46 | }; 47 | /* End PBXFrameworksBuildPhase section */ 48 | 49 | /* Begin PBXGroup section */ 50 | 096D16A21B5E60AC00CFB8F8 = { 51 | isa = PBXGroup; 52 | children = ( 53 | 096D16FC1B5E63FC00CFB8F8 /* PickerCells */, 54 | 096D16E51B5E632D00CFB8F8 /* Example */, 55 | 096D16AC1B5E60AC00CFB8F8 /* Products */, 56 | ); 57 | sourceTree = ""; 58 | }; 59 | 096D16AC1B5E60AC00CFB8F8 /* Products */ = { 60 | isa = PBXGroup; 61 | children = ( 62 | 096D16AB1B5E60AC00CFB8F8 /* Example.app */, 63 | ); 64 | name = Products; 65 | sourceTree = ""; 66 | }; 67 | 096D16E51B5E632D00CFB8F8 /* Example */ = { 68 | isa = PBXGroup; 69 | children = ( 70 | 096D16E61B5E632D00CFB8F8 /* AppDelegate.h */, 71 | 096D16E71B5E632D00CFB8F8 /* AppDelegate.m */, 72 | 096D16E81B5E632D00CFB8F8 /* Classes */, 73 | 096D16EE1B5E632D00CFB8F8 /* Storyboards */, 74 | 099CEAC41C635C8900D2605B /* Images.xcassets */, 75 | 096D16F11B5E632D00CFB8F8 /* Supporting Files */, 76 | ); 77 | path = Example; 78 | sourceTree = ""; 79 | }; 80 | 096D16E81B5E632D00CFB8F8 /* Classes */ = { 81 | isa = PBXGroup; 82 | children = ( 83 | 096D16E91B5E632D00CFB8F8 /* TableDataSource.h */, 84 | 096D16EA1B5E632D00CFB8F8 /* TableDataSource.m */, 85 | 096D16EB1B5E632D00CFB8F8 /* ViewController.h */, 86 | 096D16EC1B5E632D00CFB8F8 /* ViewController.m */, 87 | ); 88 | path = Classes; 89 | sourceTree = ""; 90 | }; 91 | 096D16EE1B5E632D00CFB8F8 /* Storyboards */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 096D16EF1B5E632D00CFB8F8 /* LaunchScreen.xib */, 95 | 096D16F01B5E632D00CFB8F8 /* Main.storyboard */, 96 | ); 97 | path = Storyboards; 98 | sourceTree = ""; 99 | }; 100 | 096D16F11B5E632D00CFB8F8 /* Supporting Files */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 096D16F21B5E632D00CFB8F8 /* Info.plist */, 104 | 096D16F31B5E632D00CFB8F8 /* main.m */, 105 | ); 106 | path = "Supporting Files"; 107 | sourceTree = ""; 108 | }; 109 | 096D16FC1B5E63FC00CFB8F8 /* PickerCells */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 096D16FD1B5E643C00CFB8F8 /* PickerCellsController.h */, 113 | 096D16FE1B5E643C00CFB8F8 /* PickerCellsController.m */, 114 | 096D17011B5E653800CFB8F8 /* PickerCellsDelegate.h */, 115 | 096D17001B5E644B00CFB8F8 /* PickerCells.h */, 116 | ); 117 | path = PickerCells; 118 | sourceTree = ""; 119 | }; 120 | /* End PBXGroup section */ 121 | 122 | /* Begin PBXNativeTarget section */ 123 | 096D16AA1B5E60AC00CFB8F8 /* Example */ = { 124 | isa = PBXNativeTarget; 125 | buildConfigurationList = 096D16CE1B5E60AD00CFB8F8 /* Build configuration list for PBXNativeTarget "Example" */; 126 | buildPhases = ( 127 | 096D16A71B5E60AC00CFB8F8 /* Sources */, 128 | 096D16A81B5E60AC00CFB8F8 /* Frameworks */, 129 | 096D16A91B5E60AC00CFB8F8 /* Resources */, 130 | ); 131 | buildRules = ( 132 | ); 133 | dependencies = ( 134 | ); 135 | name = Example; 136 | productName = PickerCells; 137 | productReference = 096D16AB1B5E60AC00CFB8F8 /* Example.app */; 138 | productType = "com.apple.product-type.application"; 139 | }; 140 | /* End PBXNativeTarget section */ 141 | 142 | /* Begin PBXProject section */ 143 | 096D16A31B5E60AC00CFB8F8 /* Project object */ = { 144 | isa = PBXProject; 145 | attributes = { 146 | LastUpgradeCheck = 0720; 147 | ORGANIZATIONNAME = "Danis Ziganshin"; 148 | TargetAttributes = { 149 | 096D16AA1B5E60AC00CFB8F8 = { 150 | CreatedOnToolsVersion = 6.4; 151 | }; 152 | }; 153 | }; 154 | buildConfigurationList = 096D16A61B5E60AC00CFB8F8 /* Build configuration list for PBXProject "Example" */; 155 | compatibilityVersion = "Xcode 3.2"; 156 | developmentRegion = English; 157 | hasScannedForEncodings = 0; 158 | knownRegions = ( 159 | en, 160 | Base, 161 | ); 162 | mainGroup = 096D16A21B5E60AC00CFB8F8; 163 | productRefGroup = 096D16AC1B5E60AC00CFB8F8 /* Products */; 164 | projectDirPath = ""; 165 | projectRoot = ""; 166 | targets = ( 167 | 096D16AA1B5E60AC00CFB8F8 /* Example */, 168 | ); 169 | }; 170 | /* End PBXProject section */ 171 | 172 | /* Begin PBXResourcesBuildPhase section */ 173 | 096D16A91B5E60AC00CFB8F8 /* Resources */ = { 174 | isa = PBXResourcesBuildPhase; 175 | buildActionMask = 2147483647; 176 | files = ( 177 | 099CEAC51C635C8900D2605B /* Images.xcassets in Resources */, 178 | 096D16F91B5E632D00CFB8F8 /* Main.storyboard in Resources */, 179 | 096D16F81B5E632D00CFB8F8 /* LaunchScreen.xib in Resources */, 180 | ); 181 | runOnlyForDeploymentPostprocessing = 0; 182 | }; 183 | /* End PBXResourcesBuildPhase section */ 184 | 185 | /* Begin PBXSourcesBuildPhase section */ 186 | 096D16A71B5E60AC00CFB8F8 /* Sources */ = { 187 | isa = PBXSourcesBuildPhase; 188 | buildActionMask = 2147483647; 189 | files = ( 190 | 096D16F61B5E632D00CFB8F8 /* ViewController.m in Sources */, 191 | 096D16FF1B5E643C00CFB8F8 /* PickerCellsController.m in Sources */, 192 | 096D16F41B5E632D00CFB8F8 /* AppDelegate.m in Sources */, 193 | 096D16FB1B5E632D00CFB8F8 /* main.m in Sources */, 194 | 096D16F51B5E632D00CFB8F8 /* TableDataSource.m in Sources */, 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | }; 198 | /* End PBXSourcesBuildPhase section */ 199 | 200 | /* Begin XCBuildConfiguration section */ 201 | 096D16CC1B5E60AD00CFB8F8 /* Debug */ = { 202 | isa = XCBuildConfiguration; 203 | buildSettings = { 204 | ALWAYS_SEARCH_USER_PATHS = NO; 205 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 206 | CLANG_CXX_LIBRARY = "libc++"; 207 | CLANG_ENABLE_MODULES = YES; 208 | CLANG_ENABLE_OBJC_ARC = YES; 209 | CLANG_WARN_BOOL_CONVERSION = YES; 210 | CLANG_WARN_CONSTANT_CONVERSION = YES; 211 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 212 | CLANG_WARN_EMPTY_BODY = YES; 213 | CLANG_WARN_ENUM_CONVERSION = YES; 214 | CLANG_WARN_INT_CONVERSION = YES; 215 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 216 | CLANG_WARN_UNREACHABLE_CODE = YES; 217 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 218 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 219 | COPY_PHASE_STRIP = NO; 220 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 221 | ENABLE_STRICT_OBJC_MSGSEND = YES; 222 | GCC_C_LANGUAGE_STANDARD = gnu99; 223 | GCC_DYNAMIC_NO_PIC = NO; 224 | GCC_NO_COMMON_BLOCKS = YES; 225 | GCC_OPTIMIZATION_LEVEL = 0; 226 | GCC_PREPROCESSOR_DEFINITIONS = ( 227 | "DEBUG=1", 228 | "$(inherited)", 229 | ); 230 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 231 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 232 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 233 | GCC_WARN_UNDECLARED_SELECTOR = YES; 234 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 235 | GCC_WARN_UNUSED_FUNCTION = YES; 236 | GCC_WARN_UNUSED_VARIABLE = YES; 237 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 238 | MTL_ENABLE_DEBUG_INFO = YES; 239 | ONLY_ACTIVE_ARCH = YES; 240 | SDKROOT = iphoneos; 241 | }; 242 | name = Debug; 243 | }; 244 | 096D16CD1B5E60AD00CFB8F8 /* Release */ = { 245 | isa = XCBuildConfiguration; 246 | buildSettings = { 247 | ALWAYS_SEARCH_USER_PATHS = NO; 248 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 249 | CLANG_CXX_LIBRARY = "libc++"; 250 | CLANG_ENABLE_MODULES = YES; 251 | CLANG_ENABLE_OBJC_ARC = YES; 252 | CLANG_WARN_BOOL_CONVERSION = YES; 253 | CLANG_WARN_CONSTANT_CONVERSION = YES; 254 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 255 | CLANG_WARN_EMPTY_BODY = YES; 256 | CLANG_WARN_ENUM_CONVERSION = YES; 257 | CLANG_WARN_INT_CONVERSION = YES; 258 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 259 | CLANG_WARN_UNREACHABLE_CODE = YES; 260 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 261 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 262 | COPY_PHASE_STRIP = NO; 263 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 264 | ENABLE_NS_ASSERTIONS = NO; 265 | ENABLE_STRICT_OBJC_MSGSEND = YES; 266 | GCC_C_LANGUAGE_STANDARD = gnu99; 267 | GCC_NO_COMMON_BLOCKS = YES; 268 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 269 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 270 | GCC_WARN_UNDECLARED_SELECTOR = YES; 271 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 272 | GCC_WARN_UNUSED_FUNCTION = YES; 273 | GCC_WARN_UNUSED_VARIABLE = YES; 274 | IPHONEOS_DEPLOYMENT_TARGET = 8.4; 275 | MTL_ENABLE_DEBUG_INFO = NO; 276 | SDKROOT = iphoneos; 277 | VALIDATE_PRODUCT = YES; 278 | }; 279 | name = Release; 280 | }; 281 | 096D16CF1B5E60AD00CFB8F8 /* Debug */ = { 282 | isa = XCBuildConfiguration; 283 | buildSettings = { 284 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 285 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 286 | INFOPLIST_FILE = "Example/Supporting Files/Info.plist"; 287 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 288 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 289 | PRODUCT_NAME = "$(TARGET_NAME)"; 290 | }; 291 | name = Debug; 292 | }; 293 | 096D16D01B5E60AD00CFB8F8 /* Release */ = { 294 | isa = XCBuildConfiguration; 295 | buildSettings = { 296 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 297 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; 298 | INFOPLIST_FILE = "Example/Supporting Files/Info.plist"; 299 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 300 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 301 | PRODUCT_NAME = "$(TARGET_NAME)"; 302 | }; 303 | name = Release; 304 | }; 305 | /* End XCBuildConfiguration section */ 306 | 307 | /* Begin XCConfigurationList section */ 308 | 096D16A61B5E60AC00CFB8F8 /* Build configuration list for PBXProject "Example" */ = { 309 | isa = XCConfigurationList; 310 | buildConfigurations = ( 311 | 096D16CC1B5E60AD00CFB8F8 /* Debug */, 312 | 096D16CD1B5E60AD00CFB8F8 /* Release */, 313 | ); 314 | defaultConfigurationIsVisible = 0; 315 | defaultConfigurationName = Release; 316 | }; 317 | 096D16CE1B5E60AD00CFB8F8 /* Build configuration list for PBXNativeTarget "Example" */ = { 318 | isa = XCConfigurationList; 319 | buildConfigurations = ( 320 | 096D16CF1B5E60AD00CFB8F8 /* Debug */, 321 | 096D16D01B5E60AD00CFB8F8 /* Release */, 322 | ); 323 | defaultConfigurationIsVisible = 0; 324 | defaultConfigurationName = Release; 325 | }; 326 | /* End XCConfigurationList section */ 327 | }; 328 | rootObject = 096D16A31B5E60AC00CFB8F8 /* Project object */; 329 | } 330 | --------------------------------------------------------------------------------