├── LICENSE ├── README.md ├── Screen.gif ├── WhdeForm.podspec ├── WhdeForm ├── Products │ └── WhdeForm.framework │ │ ├── Headers │ │ └── FormScrollView.h │ │ ├── Info.plist │ │ ├── Modules │ │ └── module.modulemap │ │ ├── WhdeForm │ │ └── _CodeSignature │ │ └── CodeResources ├── WhdeForm.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── whde.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── whde.xcuserdatad │ │ └── xcschemes │ │ ├── WhdeForm.xcscheme │ │ ├── WhdeFormTaget.xcscheme │ │ └── xcschememanagement.plist └── WhdeForm │ ├── Class │ ├── FormScrollView.h │ └── FormScrollView.m │ ├── Info.plist │ └── WhdeForm.h └── WhdeFormDemo ├── WhdeFormDemo.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ ├── OS.xcuserdatad │ │ └── UserInterfaceState.xcuserstate │ │ └── whde.xcuserdatad │ │ └── UserInterfaceState.xcuserstate └── xcuserdata │ ├── OS.xcuserdatad │ └── xcschemes │ │ └── xcschememanagement.plist │ └── whde.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── WhdeFormDemo.xcscheme │ └── xcschememanagement.plist └── WhdeFormDemo ├── AppDelegate.h ├── AppDelegate.m ├── Assets.xcassets ├── AppIcon.appiconset │ ├── Contents.json │ ├── Icon-29.0@1x.png │ ├── Icon-29.0@2x.png │ ├── Icon-29.0@3x.png │ ├── Icon-40.0@1x.png │ ├── Icon-40.0@2x.png │ ├── Icon-40.0@3x.png │ ├── Icon-50.0@1x.png │ ├── Icon-50.0@2x.png │ ├── Icon-57.0@1x.png │ ├── Icon-57.0@2x.png │ ├── Icon-60.0@2x.png │ ├── Icon-60.0@3x.png │ ├── Icon-72.0@1x.png │ ├── Icon-72.0@2x.png │ ├── Icon-76.0@1x.png │ ├── Icon-76.0@2x.png │ └── Icon-83.5@2x.png └── Contents.json ├── Base.lproj └── Main.storyboard ├── Info.plist ├── ViewController.h ├── ViewController.m ├── datas.plist └── main.m /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Whde -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # WhdeForm 2 | iOS 表格 3 | ```objective-c 4 | pod 'WhdeForm', '~> 1.0.0' 5 | ``` 6 | - 添加了Reusable机制 7 | - 添加了横(Section)表头 8 | - 添加了竖(Column)表头 9 | - 添加了左上角(TopLeftHeader)总表头 10 | - 通过FDateSource去创建各个元素,类似TableView 11 | - 添加了FIndexPath,{section, column} 12 | - 表头添加点击事件 13 | - 添加了网格 14 |

15 | 16 | # 使用 17 | ```objective-c 18 | #import "ViewController.h" 19 | #import "FormScrollView.h" 20 | @interface ViewController () { 21 | NSArray *_data; 22 | } 23 | 24 | @end 25 | 26 | @implementation ViewController 27 | 28 | - (void)viewDidLoad { 29 | [super viewDidLoad]; 30 | self.edgesForExtendedLayout = UIRectEdgeNone; 31 | self.view.autoresizingMask = UIViewAutoresizingNone; 32 | FormScrollView *table = [[FormScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height-64)]; 33 | table.contentInset = UIEdgeInsetsMake(0, 0, 0, 0); 34 | table.fDelegate = self; 35 | table.fDataSource = self; 36 | [self.view addSubview:table]; 37 | 38 | _data = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"datas" ofType:@"plist"]]; 39 | [table reloadData]; 40 | } 41 | - (FTopLeftHeaderView *)topLeftHeadViewForForm:(FormScrollView *)formScrollView { 42 | FTopLeftHeaderView *view = [formScrollView dequeueReusableTopLeftView]; 43 | if (view == NULL) { 44 | view = [[FTopLeftHeaderView alloc] initWithSectionTitle:@"行数" columnTitle:@"列数"]; 45 | } 46 | return view; 47 | } 48 | 49 | - (NSInteger)numberOfSection:(FormScrollView *)formScrollView { 50 | return _data.count; 51 | } 52 | - (NSInteger)numberOfColumn:(FormScrollView *)formScrollView { 53 | return 100; 54 | } 55 | - (CGFloat)heightForSection:(FormScrollView *)formScrollView { 56 | return 44; 57 | } 58 | - (CGFloat)widthForColumn:(FormScrollView *)formScrollView { 59 | return 80; 60 | } 61 | - (FormSectionHeaderView *)form:(FormScrollView *)formScrollView sectionHeaderAtSection:(NSInteger)section { 62 | FormSectionHeaderView *header = [formScrollView dequeueReusableSectionWithIdentifier:@"Section"]; 63 | if (header == NULL) { 64 | header = [[FormSectionHeaderView alloc] initWithIdentifier:@"Section"]; 65 | } 66 | [header setTitle:[NSString stringWithFormat:@"第%ld行", (long)section] forState:UIControlStateNormal]; 67 | /*[header setBackgroundColor:[UIColor redColor]];*/ 68 | [header setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 69 | return header; 70 | } 71 | - (FormColumnHeaderView *)form:(FormScrollView *)formScrollView columnHeaderAtColumn:(NSInteger)column { 72 | FormColumnHeaderView *header = [formScrollView dequeueReusableColumnWithIdentifier:@"Column"]; 73 | if (header == NULL) { 74 | header = [[FormColumnHeaderView alloc] initWithIdentifier:@"Column"]; 75 | } 76 | [header setTitle:[NSString stringWithFormat:@"第%ld列", (long)column] forState:UIControlStateNormal]; 77 | /*[header setBackgroundColor:[UIColor greenColor]];*/ 78 | [header setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 79 | return header; 80 | } 81 | - (FormCell *)form:(FormScrollView *)formScrollView cellForColumnAtIndexPath:(FIndexPath *)indexPath { 82 | FormCell *cell = [formScrollView dequeueReusableCellWithIdentifier:@"Cell"]; 83 | NSLog(@"%@", cell); 84 | if (cell == NULL) { 85 | cell = [[FormCell alloc] initWithIdentifier:@"Cell"]; 86 | static int i=0; 87 | i++; 88 | NSLog(@"%d--%ld", i, (long)indexPath.section); 89 | } 90 | NSDictionary *dic = [_data objectAtIndex:indexPath.section]; 91 | [cell setTitle:dic[@"name"] forState:UIControlStateNormal]; 92 | [cell setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 93 | /*[cell setBackgroundColor:[UIColor yellowColor]];*/ 94 | return cell; 95 | } 96 | - (void)form:(FormScrollView *)formScrollView didSelectSectionAtIndex:(NSInteger)section { 97 | NSLog(@"Click Section At Index:%ld", (long)section); 98 | } 99 | - (void)form:(FormScrollView *)formScrollView didSelectColumnAtIndex:(NSInteger)column { 100 | NSLog(@"Click Cloumn At Index:%ld", (long)column); 101 | } 102 | - (void)form:(FormScrollView *)formScrollView didSelectCellAtIndexPath:(FIndexPath *)indexPath { 103 | NSLog(@"Click Cell At IndexPath:%ld,%ld", (long)indexPath.section, (long)indexPath.column); 104 | } 105 | - (void)didReceiveMemoryWarning { 106 | [super didReceiveMemoryWarning]; 107 | } 108 | 109 | @end 110 | 111 | ``` 112 | -------------------------------------------------------------------------------- /Screen.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/Screen.gif -------------------------------------------------------------------------------- /WhdeForm.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "WhdeForm" 3 | s.version = "1.0.0" 4 | s.summary = "iOS Form 表格." 5 | s.homepage = "https://github.com/whde/WhdeForm" 6 | s.license = 'MIT' 7 | s.author = { "Whde" => "460290973@qq.com" } 8 | s.platform = :ios, "7.0" 9 | s.source = { :git => "https://github.com/whde/WhdeForm.git", :tag => s.version.to_s } 10 | s.source_files = 'WhdeForm/WhdeForm/Class/*' 11 | s.frameworks = 'Foundation' 12 | s.requires_arc = true 13 | s.description = <<-DESC 14 | It is a Form used on iOS, which implement by Objective-C, use Reusable System to save your App Memory. 15 | DESC 16 | end 17 | 18 | -------------------------------------------------------------------------------- /WhdeForm/Products/WhdeForm.framework/Headers/FormScrollView.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormScrollView.h 3 | // WhdeFormDemo 4 | // 5 | // Created by whde on 16/5/4. 6 | // Copyright © 2016年 whde. All rights reserved. 7 | // 8 | 9 | #import 10 | @class FIndexPath; 11 | @class FormScrollView; 12 | @class FormColumnHeaderView; 13 | @class FormSectionHeaderView; 14 | @class FormCell; 15 | @class FTopLeftHeaderView; 16 | @protocol FDelegate 17 | @optional 18 | - (void)form:(FormScrollView *)formScrollView didSelectCellAtIndexPath:(FIndexPath *)indexPath; 19 | - (void)form:(FormScrollView *)formScrollView didSelectSectionAtIndex:(NSInteger)section; 20 | - (void)form:(FormScrollView *)formScrollView didSelectColumnAtIndex:(NSInteger)column; 21 | @end 22 | @protocol FDataSource 23 | @required 24 | - (NSInteger)numberOfSection:(FormScrollView *)formScrollView; 25 | - (NSInteger)numberOfColumn:(FormScrollView *)formScrollView; 26 | - (CGFloat)heightForSection:(FormScrollView *)formScrollView; 27 | - (CGFloat)widthForColumn:(FormScrollView *)formScrollView; 28 | - (FTopLeftHeaderView *)topLeftHeadViewForForm:(FormScrollView *)formScrollView; 29 | - (FormSectionHeaderView *)form:(FormScrollView *)formScrollView sectionHeaderAtSection:(NSInteger)section; 30 | - (FormColumnHeaderView *)form:(FormScrollView *)formScrollView columnHeaderAtColumn:(NSInteger)column; 31 | - (FormCell *)form:(FormScrollView *)formScrollView cellForColumnAtIndexPath:(FIndexPath *)indexPath; 32 | @end 33 | 34 | @interface FormScrollView : UIScrollView 35 | @property (nonatomic, assign) idfDelegate; 36 | @property (nonatomic, assign) idfDataSource; 37 | - (FormColumnHeaderView *)dequeueReusableColumnWithIdentifier:(NSString *)identifier; 38 | - (FormSectionHeaderView *)dequeueReusableSectionWithIdentifier:(NSString *)identifier; 39 | - (FormCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier; 40 | - (FTopLeftHeaderView *)dequeueReusableTopLeftView; 41 | - (void)reloadData; 42 | 43 | @end 44 | 45 | //// Cell 46 | @interface FormCell : UIButton 47 | @property (nonatomic, copy, readonly) NSString *identifier; 48 | @property (nonatomic, copy, readonly) FIndexPath *indexPath; 49 | - (instancetype)initWithIdentifier:(NSString *)identifier; 50 | - (void)setIndexPath:(FIndexPath *)indexPath; 51 | @end 52 | 53 | //// FormColumnHeaderView 54 | @interface FormColumnHeaderView : UIButton 55 | @property (nonatomic, copy, readonly) NSString *identifier; 56 | @property (nonatomic, assign, readonly) NSInteger column; 57 | - (instancetype)initWithIdentifier:(NSString *)identifier; 58 | - (void)setColumn:(NSInteger)column; 59 | @end 60 | 61 | //// FormSectionHeaderView 62 | @interface FormSectionHeaderView : UIButton 63 | @property (nonatomic, copy, readonly) NSString *identifier; 64 | @property (nonatomic, assign, readonly) NSInteger section; 65 | - (instancetype)initWithIdentifier:(NSString *)identifier; 66 | - (void)setSection:(NSInteger)section; 67 | @end 68 | 69 | //// FTopLeftHeaderView 70 | @interface FTopLeftHeaderView : UIView 71 | @property (nonatomic, copy, readonly) NSString *sectionTitle; 72 | @property (nonatomic, copy, readonly) NSString *columnTitle; 73 | - (instancetype)initWithSectionTitle:(NSString *)sectionTitle columnTitle:(NSString *)columnTitle; 74 | @end 75 | 76 | //// IndexPath 77 | @interface FIndexPath : NSObject 78 | + (instancetype)indexPathForSection:(NSInteger)section inColumn:(NSInteger)column; 79 | @property (nonatomic, assign) NSInteger section; 80 | @property (nonatomic, assign) NSInteger column; 81 | @end 82 | -------------------------------------------------------------------------------- /WhdeForm/Products/WhdeForm.framework/Info.plist: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeForm/Products/WhdeForm.framework/Info.plist -------------------------------------------------------------------------------- /WhdeForm/Products/WhdeForm.framework/Modules/module.modulemap: -------------------------------------------------------------------------------- 1 | framework module WhdeForm { 2 | umbrella header "WhdeForm.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /WhdeForm/Products/WhdeForm.framework/WhdeForm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeForm/Products/WhdeForm.framework/WhdeForm -------------------------------------------------------------------------------- /WhdeForm/Products/WhdeForm.framework/_CodeSignature/CodeResources: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | files 6 | 7 | Headers/FormScrollView.h 8 | 9 | 4UQup5lGN0UccH+UcuXM/At/y50= 10 | 11 | Info.plist 12 | 13 | nsPTRCteVKZykv+tLq0snJUs3Ak= 14 | 15 | Modules/module.modulemap 16 | 17 | LaHqnGwAeIQOt4MU6gsagQPjyJ4= 18 | 19 | 20 | files2 21 | 22 | Headers/FormScrollView.h 23 | 24 | hash 25 | 26 | 4UQup5lGN0UccH+UcuXM/At/y50= 27 | 28 | hash2 29 | 30 | 5IjUHcKhy4lJwGttrGu7McrN9dmq4dDpnjr9qB5ZUL8= 31 | 32 | 33 | Modules/module.modulemap 34 | 35 | hash 36 | 37 | LaHqnGwAeIQOt4MU6gsagQPjyJ4= 38 | 39 | hash2 40 | 41 | mnJ3MO26H8ezI4XrNEngQ99fet2bHca0BY/9XCoNLEk= 42 | 43 | 44 | 45 | rules 46 | 47 | ^ 48 | 49 | ^.*\.lproj/ 50 | 51 | optional 52 | 53 | weight 54 | 1000 55 | 56 | ^.*\.lproj/locversion.plist$ 57 | 58 | omit 59 | 60 | weight 61 | 1100 62 | 63 | ^version.plist$ 64 | 65 | 66 | rules2 67 | 68 | .*\.dSYM($|/) 69 | 70 | weight 71 | 11 72 | 73 | ^ 74 | 75 | weight 76 | 20 77 | 78 | ^(.*/)?\.DS_Store$ 79 | 80 | omit 81 | 82 | weight 83 | 2000 84 | 85 | ^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/ 86 | 87 | nested 88 | 89 | weight 90 | 10 91 | 92 | ^.* 93 | 94 | ^.*\.lproj/ 95 | 96 | optional 97 | 98 | weight 99 | 1000 100 | 101 | ^.*\.lproj/locversion.plist$ 102 | 103 | omit 104 | 105 | weight 106 | 1100 107 | 108 | ^Info\.plist$ 109 | 110 | omit 111 | 112 | weight 113 | 20 114 | 115 | ^PkgInfo$ 116 | 117 | omit 118 | 119 | weight 120 | 20 121 | 122 | ^[^/]+$ 123 | 124 | nested 125 | 126 | weight 127 | 10 128 | 129 | ^embedded\.provisionprofile$ 130 | 131 | weight 132 | 20 133 | 134 | ^version\.plist$ 135 | 136 | weight 137 | 20 138 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /WhdeForm/WhdeForm.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXAggregateTarget section */ 10 | F88601F01CDB55C10044AB21 /* WhdeFormTaget */ = { 11 | isa = PBXAggregateTarget; 12 | buildConfigurationList = F88601F11CDB55C10044AB21 /* Build configuration list for PBXAggregateTarget "WhdeFormTaget" */; 13 | buildPhases = ( 14 | F88601F41CDB55C70044AB21 /* ShellScript */, 15 | ); 16 | dependencies = ( 17 | ); 18 | name = WhdeFormTaget; 19 | productName = WhdeFormTaget; 20 | }; 21 | /* End PBXAggregateTarget section */ 22 | 23 | /* Begin PBXBuildFile section */ 24 | F84BB2BD1CDC4C6900EB7E30 /* WhdeForm.h in Headers */ = {isa = PBXBuildFile; fileRef = F84BB2BC1CDC4C6900EB7E30 /* WhdeForm.h */; }; 25 | F88601ED1CDB55A80044AB21 /* FormScrollView.h in Headers */ = {isa = PBXBuildFile; fileRef = F88601EA1CDB55A80044AB21 /* FormScrollView.h */; settings = {ATTRIBUTES = (Public, ); }; }; 26 | F88601EE1CDB55A80044AB21 /* FormScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = F88601EB1CDB55A80044AB21 /* FormScrollView.m */; }; 27 | /* End PBXBuildFile section */ 28 | 29 | /* Begin PBXFileReference section */ 30 | F84BB2BC1CDC4C6900EB7E30 /* WhdeForm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WhdeForm.h; sourceTree = ""; }; 31 | F88601D01CDB54B50044AB21 /* WhdeForm.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = WhdeForm.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 32 | F88601D51CDB54B50044AB21 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 33 | F88601EA1CDB55A80044AB21 /* FormScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormScrollView.h; sourceTree = ""; }; 34 | F88601EB1CDB55A80044AB21 /* FormScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FormScrollView.m; sourceTree = ""; }; 35 | /* End PBXFileReference section */ 36 | 37 | /* Begin PBXFrameworksBuildPhase section */ 38 | F88601CC1CDB54B50044AB21 /* Frameworks */ = { 39 | isa = PBXFrameworksBuildPhase; 40 | buildActionMask = 2147483647; 41 | files = ( 42 | ); 43 | runOnlyForDeploymentPostprocessing = 0; 44 | }; 45 | /* End PBXFrameworksBuildPhase section */ 46 | 47 | /* Begin PBXGroup section */ 48 | F88601C61CDB54B50044AB21 = { 49 | isa = PBXGroup; 50 | children = ( 51 | F88601D21CDB54B50044AB21 /* WhdeForm */, 52 | F88601D11CDB54B50044AB21 /* Products */, 53 | ); 54 | sourceTree = ""; 55 | }; 56 | F88601D11CDB54B50044AB21 /* Products */ = { 57 | isa = PBXGroup; 58 | children = ( 59 | F88601D01CDB54B50044AB21 /* WhdeForm.framework */, 60 | ); 61 | name = Products; 62 | sourceTree = ""; 63 | }; 64 | F88601D21CDB54B50044AB21 /* WhdeForm */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | F84BB2BC1CDC4C6900EB7E30 /* WhdeForm.h */, 68 | F88601E91CDB55A80044AB21 /* Class */, 69 | F88601D51CDB54B50044AB21 /* Info.plist */, 70 | ); 71 | path = WhdeForm; 72 | sourceTree = ""; 73 | }; 74 | F88601E91CDB55A80044AB21 /* Class */ = { 75 | isa = PBXGroup; 76 | children = ( 77 | F88601EA1CDB55A80044AB21 /* FormScrollView.h */, 78 | F88601EB1CDB55A80044AB21 /* FormScrollView.m */, 79 | ); 80 | path = Class; 81 | sourceTree = ""; 82 | }; 83 | /* End PBXGroup section */ 84 | 85 | /* Begin PBXHeadersBuildPhase section */ 86 | F88601CD1CDB54B50044AB21 /* Headers */ = { 87 | isa = PBXHeadersBuildPhase; 88 | buildActionMask = 2147483647; 89 | files = ( 90 | F84BB2BD1CDC4C6900EB7E30 /* WhdeForm.h in Headers */, 91 | F88601ED1CDB55A80044AB21 /* FormScrollView.h in Headers */, 92 | ); 93 | runOnlyForDeploymentPostprocessing = 0; 94 | }; 95 | /* End PBXHeadersBuildPhase section */ 96 | 97 | /* Begin PBXNativeTarget section */ 98 | F88601CF1CDB54B50044AB21 /* WhdeForm */ = { 99 | isa = PBXNativeTarget; 100 | buildConfigurationList = F88601D81CDB54B50044AB21 /* Build configuration list for PBXNativeTarget "WhdeForm" */; 101 | buildPhases = ( 102 | F88601CB1CDB54B50044AB21 /* Sources */, 103 | F88601CC1CDB54B50044AB21 /* Frameworks */, 104 | F88601CD1CDB54B50044AB21 /* Headers */, 105 | F88601CE1CDB54B50044AB21 /* Resources */, 106 | ); 107 | buildRules = ( 108 | ); 109 | dependencies = ( 110 | ); 111 | name = WhdeForm; 112 | productName = WhdeForm; 113 | productReference = F88601D01CDB54B50044AB21 /* WhdeForm.framework */; 114 | productType = "com.apple.product-type.framework"; 115 | }; 116 | /* End PBXNativeTarget section */ 117 | 118 | /* Begin PBXProject section */ 119 | F88601C71CDB54B50044AB21 /* Project object */ = { 120 | isa = PBXProject; 121 | attributes = { 122 | LastUpgradeCheck = 0730; 123 | ORGANIZATIONNAME = whde; 124 | TargetAttributes = { 125 | F88601CF1CDB54B50044AB21 = { 126 | CreatedOnToolsVersion = 7.3; 127 | }; 128 | F88601F01CDB55C10044AB21 = { 129 | CreatedOnToolsVersion = 7.3; 130 | }; 131 | }; 132 | }; 133 | buildConfigurationList = F88601CA1CDB54B50044AB21 /* Build configuration list for PBXProject "WhdeForm" */; 134 | compatibilityVersion = "Xcode 3.2"; 135 | developmentRegion = English; 136 | hasScannedForEncodings = 0; 137 | knownRegions = ( 138 | en, 139 | ); 140 | mainGroup = F88601C61CDB54B50044AB21; 141 | productRefGroup = F88601D11CDB54B50044AB21 /* Products */; 142 | projectDirPath = ""; 143 | projectRoot = ""; 144 | targets = ( 145 | F88601CF1CDB54B50044AB21 /* WhdeForm */, 146 | F88601F01CDB55C10044AB21 /* WhdeFormTaget */, 147 | ); 148 | }; 149 | /* End PBXProject section */ 150 | 151 | /* Begin PBXResourcesBuildPhase section */ 152 | F88601CE1CDB54B50044AB21 /* Resources */ = { 153 | isa = PBXResourcesBuildPhase; 154 | buildActionMask = 2147483647; 155 | files = ( 156 | ); 157 | runOnlyForDeploymentPostprocessing = 0; 158 | }; 159 | /* End PBXResourcesBuildPhase section */ 160 | 161 | /* Begin PBXShellScriptBuildPhase section */ 162 | F88601F41CDB55C70044AB21 /* ShellScript */ = { 163 | isa = PBXShellScriptBuildPhase; 164 | buildActionMask = 2147483647; 165 | files = ( 166 | ); 167 | inputPaths = ( 168 | ); 169 | outputPaths = ( 170 | ); 171 | runOnlyForDeploymentPostprocessing = 0; 172 | shellPath = /bin/sh; 173 | shellScript = "# Sets the target folders and the final framework product.\n# 如果工程名称和Framework的Target名称不一样的话,要自定义FMKNAME\n# 例如: FMK_NAME = \"MyFramework\"\nFMK_NAME=${PROJECT_NAME}\n# Install dir will be the final output to the framework.\n# The following line create it in the root folder of the current project.\nINSTALL_DIR=${SRCROOT}/Products/${FMK_NAME}.framework\n# Working dir will be deleted after the framework creation.\nWRK_DIR=build\nDEVICE_DIR=${WRK_DIR}/Release-iphoneos/${FMK_NAME}.framework\nSIMULATOR_DIR=${WRK_DIR}/Release-iphonesimulator/${FMK_NAME}.framework\n# -configuration ${CONFIGURATION}\n# Clean and Building both architectures.\nxcodebuild -configuration \"Release\" -target \"${FMK_NAME}\" -sdk iphoneos clean build\nxcodebuild -configuration \"Release\" -target \"${FMK_NAME}\" -sdk iphonesimulator clean build\n# Cleaning the oldest.\nif [ -d \"${INSTALL_DIR}\" ]\nthen\nrm -rf \"${INSTALL_DIR}\"\nfi\nmkdir -p \"${INSTALL_DIR}\"\ncp -R \"${DEVICE_DIR}/\" \"${INSTALL_DIR}/\"\n# Uses the Lipo Tool to merge both binary files (i386 + armv6/armv7) into one Universal final product.\nlipo -create \"${DEVICE_DIR}/${FMK_NAME}\" \"${SIMULATOR_DIR}/${FMK_NAME}\" -output \"${INSTALL_DIR}/${FMK_NAME}\"\nrm -r \"${WRK_DIR}\"\nopen \"${INSTALL_DIR}\""; 174 | }; 175 | /* End PBXShellScriptBuildPhase section */ 176 | 177 | /* Begin PBXSourcesBuildPhase section */ 178 | F88601CB1CDB54B50044AB21 /* Sources */ = { 179 | isa = PBXSourcesBuildPhase; 180 | buildActionMask = 2147483647; 181 | files = ( 182 | F88601EE1CDB55A80044AB21 /* FormScrollView.m in Sources */, 183 | ); 184 | runOnlyForDeploymentPostprocessing = 0; 185 | }; 186 | /* End PBXSourcesBuildPhase section */ 187 | 188 | /* Begin XCBuildConfiguration section */ 189 | F88601D61CDB54B50044AB21 /* Debug */ = { 190 | isa = XCBuildConfiguration; 191 | buildSettings = { 192 | ALWAYS_SEARCH_USER_PATHS = NO; 193 | CLANG_ANALYZER_NONNULL = YES; 194 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 195 | CLANG_CXX_LIBRARY = "libc++"; 196 | CLANG_ENABLE_MODULES = YES; 197 | CLANG_ENABLE_OBJC_ARC = YES; 198 | CLANG_WARN_BOOL_CONVERSION = YES; 199 | CLANG_WARN_CONSTANT_CONVERSION = YES; 200 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 201 | CLANG_WARN_EMPTY_BODY = YES; 202 | CLANG_WARN_ENUM_CONVERSION = YES; 203 | CLANG_WARN_INT_CONVERSION = YES; 204 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 205 | CLANG_WARN_UNREACHABLE_CODE = YES; 206 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 207 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 208 | COPY_PHASE_STRIP = NO; 209 | CURRENT_PROJECT_VERSION = 1; 210 | DEBUG_INFORMATION_FORMAT = dwarf; 211 | ENABLE_STRICT_OBJC_MSGSEND = YES; 212 | ENABLE_TESTABILITY = YES; 213 | GCC_C_LANGUAGE_STANDARD = gnu99; 214 | GCC_DYNAMIC_NO_PIC = NO; 215 | GCC_NO_COMMON_BLOCKS = YES; 216 | GCC_OPTIMIZATION_LEVEL = 0; 217 | GCC_PREPROCESSOR_DEFINITIONS = ( 218 | "DEBUG=1", 219 | "$(inherited)", 220 | ); 221 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 222 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 223 | GCC_WARN_UNDECLARED_SELECTOR = YES; 224 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 225 | GCC_WARN_UNUSED_FUNCTION = YES; 226 | GCC_WARN_UNUSED_VARIABLE = YES; 227 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 228 | MTL_ENABLE_DEBUG_INFO = YES; 229 | ONLY_ACTIVE_ARCH = YES; 230 | SDKROOT = iphoneos; 231 | TARGETED_DEVICE_FAMILY = "1,2"; 232 | VERSIONING_SYSTEM = "apple-generic"; 233 | VERSION_INFO_PREFIX = ""; 234 | }; 235 | name = Debug; 236 | }; 237 | F88601D71CDB54B50044AB21 /* Release */ = { 238 | isa = XCBuildConfiguration; 239 | buildSettings = { 240 | ALWAYS_SEARCH_USER_PATHS = NO; 241 | CLANG_ANALYZER_NONNULL = YES; 242 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 243 | CLANG_CXX_LIBRARY = "libc++"; 244 | CLANG_ENABLE_MODULES = YES; 245 | CLANG_ENABLE_OBJC_ARC = YES; 246 | CLANG_WARN_BOOL_CONVERSION = YES; 247 | CLANG_WARN_CONSTANT_CONVERSION = YES; 248 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 249 | CLANG_WARN_EMPTY_BODY = YES; 250 | CLANG_WARN_ENUM_CONVERSION = YES; 251 | CLANG_WARN_INT_CONVERSION = YES; 252 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 253 | CLANG_WARN_UNREACHABLE_CODE = YES; 254 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 255 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 256 | COPY_PHASE_STRIP = NO; 257 | CURRENT_PROJECT_VERSION = 1; 258 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 259 | ENABLE_NS_ASSERTIONS = NO; 260 | ENABLE_STRICT_OBJC_MSGSEND = YES; 261 | GCC_C_LANGUAGE_STANDARD = gnu99; 262 | GCC_NO_COMMON_BLOCKS = YES; 263 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 264 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 265 | GCC_WARN_UNDECLARED_SELECTOR = YES; 266 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 267 | GCC_WARN_UNUSED_FUNCTION = YES; 268 | GCC_WARN_UNUSED_VARIABLE = YES; 269 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 270 | MTL_ENABLE_DEBUG_INFO = NO; 271 | SDKROOT = iphoneos; 272 | TARGETED_DEVICE_FAMILY = "1,2"; 273 | VALIDATE_PRODUCT = YES; 274 | VERSIONING_SYSTEM = "apple-generic"; 275 | VERSION_INFO_PREFIX = ""; 276 | }; 277 | name = Release; 278 | }; 279 | F88601D91CDB54B50044AB21 /* Debug */ = { 280 | isa = XCBuildConfiguration; 281 | buildSettings = { 282 | DEFINES_MODULE = YES; 283 | DYLIB_COMPATIBILITY_VERSION = 1; 284 | DYLIB_CURRENT_VERSION = 1; 285 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 286 | INFOPLIST_FILE = WhdeForm/Info.plist; 287 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 288 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 289 | PRODUCT_BUNDLE_IDENTIFIER = com.ziyoubang.WhdeForm; 290 | PRODUCT_NAME = "$(TARGET_NAME)"; 291 | SKIP_INSTALL = YES; 292 | }; 293 | name = Debug; 294 | }; 295 | F88601DA1CDB54B50044AB21 /* Release */ = { 296 | isa = XCBuildConfiguration; 297 | buildSettings = { 298 | DEFINES_MODULE = YES; 299 | DYLIB_COMPATIBILITY_VERSION = 1; 300 | DYLIB_CURRENT_VERSION = 1; 301 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 302 | INFOPLIST_FILE = WhdeForm/Info.plist; 303 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 304 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 305 | PRODUCT_BUNDLE_IDENTIFIER = com.ziyoubang.WhdeForm; 306 | PRODUCT_NAME = "$(TARGET_NAME)"; 307 | SKIP_INSTALL = YES; 308 | }; 309 | name = Release; 310 | }; 311 | F88601F21CDB55C10044AB21 /* Debug */ = { 312 | isa = XCBuildConfiguration; 313 | buildSettings = { 314 | MACH_O_TYPE = staticlib; 315 | PRODUCT_NAME = "$(TARGET_NAME)"; 316 | }; 317 | name = Debug; 318 | }; 319 | F88601F31CDB55C10044AB21 /* Release */ = { 320 | isa = XCBuildConfiguration; 321 | buildSettings = { 322 | MACH_O_TYPE = staticlib; 323 | PRODUCT_NAME = "$(TARGET_NAME)"; 324 | }; 325 | name = Release; 326 | }; 327 | /* End XCBuildConfiguration section */ 328 | 329 | /* Begin XCConfigurationList section */ 330 | F88601CA1CDB54B50044AB21 /* Build configuration list for PBXProject "WhdeForm" */ = { 331 | isa = XCConfigurationList; 332 | buildConfigurations = ( 333 | F88601D61CDB54B50044AB21 /* Debug */, 334 | F88601D71CDB54B50044AB21 /* Release */, 335 | ); 336 | defaultConfigurationIsVisible = 0; 337 | defaultConfigurationName = Release; 338 | }; 339 | F88601D81CDB54B50044AB21 /* Build configuration list for PBXNativeTarget "WhdeForm" */ = { 340 | isa = XCConfigurationList; 341 | buildConfigurations = ( 342 | F88601D91CDB54B50044AB21 /* Debug */, 343 | F88601DA1CDB54B50044AB21 /* Release */, 344 | ); 345 | defaultConfigurationIsVisible = 0; 346 | defaultConfigurationName = Release; 347 | }; 348 | F88601F11CDB55C10044AB21 /* Build configuration list for PBXAggregateTarget "WhdeFormTaget" */ = { 349 | isa = XCConfigurationList; 350 | buildConfigurations = ( 351 | F88601F21CDB55C10044AB21 /* Debug */, 352 | F88601F31CDB55C10044AB21 /* Release */, 353 | ); 354 | defaultConfigurationIsVisible = 0; 355 | defaultConfigurationName = Release; 356 | }; 357 | /* End XCConfigurationList section */ 358 | }; 359 | rootObject = F88601C71CDB54B50044AB21 /* Project object */; 360 | } 361 | -------------------------------------------------------------------------------- /WhdeForm/WhdeForm.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WhdeForm/WhdeForm.xcodeproj/project.xcworkspace/xcuserdata/whde.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeForm/WhdeForm.xcodeproj/project.xcworkspace/xcuserdata/whde.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WhdeForm/WhdeForm.xcodeproj/xcuserdata/whde.xcuserdatad/xcschemes/WhdeForm.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /WhdeForm/WhdeForm.xcodeproj/xcuserdata/whde.xcuserdatad/xcschemes/WhdeFormTaget.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /WhdeForm/WhdeForm.xcodeproj/xcuserdata/whde.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WhdeForm.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | WhdeFormTaget.xcscheme 13 | 14 | orderHint 15 | 1 16 | 17 | 18 | SuppressBuildableAutocreation 19 | 20 | F88601CF1CDB54B50044AB21 21 | 22 | primary 23 | 24 | 25 | F88601F01CDB55C10044AB21 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /WhdeForm/WhdeForm/Class/FormScrollView.h: -------------------------------------------------------------------------------- 1 | // 2 | // FormScrollView.h 3 | // WhdeFormDemo 4 | // 5 | // Created by whde on 16/5/4. 6 | // Copyright © 2016年 whde. All rights reserved. 7 | // 8 | 9 | #import 10 | @class FIndexPath; 11 | @class FormScrollView; 12 | @class FormColumnHeaderView; 13 | @class FormSectionHeaderView; 14 | @class FormCell; 15 | @class FTopLeftHeaderView; 16 | @protocol FDelegate 17 | @optional 18 | - (void)form:(FormScrollView *)formScrollView didSelectCellAtIndexPath:(FIndexPath *)indexPath; 19 | - (void)form:(FormScrollView *)formScrollView didSelectSectionAtIndex:(NSInteger)section; 20 | - (void)form:(FormScrollView *)formScrollView didSelectColumnAtIndex:(NSInteger)column; 21 | @end 22 | @protocol FDataSource 23 | @required 24 | - (NSInteger)numberOfSection:(FormScrollView *)formScrollView; 25 | - (NSInteger)numberOfColumn:(FormScrollView *)formScrollView; 26 | - (CGFloat)heightForSection:(FormScrollView *)formScrollView; 27 | - (CGFloat)widthForColumn:(FormScrollView *)formScrollView; 28 | - (FTopLeftHeaderView *)topLeftHeadViewForForm:(FormScrollView *)formScrollView; 29 | - (FormSectionHeaderView *)form:(FormScrollView *)formScrollView sectionHeaderAtSection:(NSInteger)section; 30 | - (FormColumnHeaderView *)form:(FormScrollView *)formScrollView columnHeaderAtColumn:(NSInteger)column; 31 | - (FormCell *)form:(FormScrollView *)formScrollView cellForColumnAtIndexPath:(FIndexPath *)indexPath; 32 | @end 33 | 34 | @interface FormScrollView : UIScrollView 35 | @property (nonatomic, assign) idfDelegate; 36 | @property (nonatomic, assign) idfDataSource; 37 | - (FormColumnHeaderView *)dequeueReusableColumnWithIdentifier:(NSString *)identifier; 38 | - (FormSectionHeaderView *)dequeueReusableSectionWithIdentifier:(NSString *)identifier; 39 | - (FormCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier; 40 | - (FTopLeftHeaderView *)dequeueReusableTopLeftView; 41 | - (void)reloadData; 42 | 43 | @end 44 | 45 | //// Cell 46 | @interface FormCell : UIButton 47 | @property (nonatomic, copy, readonly) NSString *identifier; 48 | @property (nonatomic, copy, readonly) FIndexPath *indexPath; 49 | - (instancetype)initWithIdentifier:(NSString *)identifier; 50 | - (void)setIndexPath:(FIndexPath *)indexPath; 51 | @end 52 | 53 | //// FormColumnHeaderView 54 | @interface FormColumnHeaderView : UIButton 55 | @property (nonatomic, copy, readonly) NSString *identifier; 56 | @property (nonatomic, assign, readonly) NSInteger column; 57 | - (instancetype)initWithIdentifier:(NSString *)identifier; 58 | - (void)setColumn:(NSInteger)column; 59 | @end 60 | 61 | //// FormSectionHeaderView 62 | @interface FormSectionHeaderView : UIButton 63 | @property (nonatomic, copy, readonly) NSString *identifier; 64 | @property (nonatomic, assign, readonly) NSInteger section; 65 | - (instancetype)initWithIdentifier:(NSString *)identifier; 66 | - (void)setSection:(NSInteger)section; 67 | @end 68 | 69 | //// FTopLeftHeaderView 70 | @interface FTopLeftHeaderView : UIView 71 | @property (nonatomic, copy, readonly) NSString *sectionTitle; 72 | @property (nonatomic, copy, readonly) NSString *columnTitle; 73 | - (instancetype)initWithSectionTitle:(NSString *)sectionTitle columnTitle:(NSString *)columnTitle; 74 | @end 75 | 76 | //// IndexPath 77 | @interface FIndexPath : NSObject 78 | + (instancetype)indexPathForSection:(NSInteger)section inColumn:(NSInteger)column; 79 | @property (nonatomic, assign) NSInteger section; 80 | @property (nonatomic, assign) NSInteger column; 81 | @end 82 | -------------------------------------------------------------------------------- /WhdeForm/WhdeForm/Class/FormScrollView.m: -------------------------------------------------------------------------------- 1 | // 2 | // FormScrollView.m 3 | // WhdeFormDemo 4 | // 5 | // Created by whde on 16/5/4. 6 | // Copyright © 2016年 whde. All rights reserved. 7 | // 8 | 9 | #import "FormScrollView.h" 10 | @interface FormScrollView () { 11 | NSMutableArray *_reusableSectionsHeaders; 12 | NSMutableArray *_reusableColumnHeaders; 13 | NSMutableArray *_reusableCells; 14 | NSMutableArray *_reusableTopLeftHeaders; 15 | 16 | NSInteger _numberSection; 17 | NSInteger _numberColumn; 18 | 19 | CGFloat _width; 20 | CGFloat _height; 21 | 22 | FIndexPath *_firstIndexPath; 23 | FIndexPath *_maxIndexPath; 24 | FTopLeftHeaderView *_topLeftView; 25 | } 26 | @end 27 | @implementation FormScrollView 28 | ////instance 29 | - (id)init { 30 | return [self initWithFrame:CGRectZero]; 31 | } 32 | 33 | - (id)initWithFrame:(CGRect)frame { 34 | if ((self = [super initWithFrame:frame])) { 35 | [self commonInit]; 36 | } 37 | return self; 38 | } 39 | 40 | - (id)initWithCoder:(NSCoder *)aDecoder { 41 | if ((self = [super initWithCoder:aDecoder])) { 42 | [self commonInit]; 43 | } 44 | 45 | return self; 46 | } 47 | - (void)commonInit { 48 | _reusableColumnHeaders = [[NSMutableArray alloc] init]; 49 | _reusableSectionsHeaders = [[NSMutableArray alloc] init]; 50 | _reusableCells = [[NSMutableArray alloc] init]; 51 | _reusableTopLeftHeaders = [[NSMutableArray alloc] init]; 52 | _firstIndexPath = [FIndexPath indexPathForSection:-1 inColumn:-1]; 53 | _maxIndexPath = [FIndexPath indexPathForSection:-1 inColumn:-1]; 54 | self.bounces = NO; 55 | } 56 | 57 | ////deq 58 | - (FormColumnHeaderView *)dequeueReusableColumnWithIdentifier:(NSString *)identifier { 59 | FormColumnHeaderView *columnHeader = nil; 60 | for (FormColumnHeaderView *reusableHeader in _reusableColumnHeaders) { 61 | if ([reusableHeader.identifier isEqualToString:identifier]) { 62 | columnHeader = reusableHeader; 63 | break; 64 | } 65 | } 66 | if (columnHeader) { 67 | [_reusableColumnHeaders removeObject:columnHeader]; 68 | } 69 | return columnHeader; 70 | } 71 | - (FormSectionHeaderView *)dequeueReusableSectionWithIdentifier:(NSString *)identifier { 72 | FormSectionHeaderView *sectionHeader = nil; 73 | for (FormSectionHeaderView *reusableSection in _reusableSectionsHeaders) { 74 | if ([reusableSection.identifier isEqualToString:identifier]) { 75 | sectionHeader = reusableSection; 76 | break; 77 | } 78 | } 79 | 80 | if (sectionHeader) { 81 | [_reusableSectionsHeaders removeObject:sectionHeader]; 82 | } 83 | return sectionHeader; 84 | } 85 | - (FormCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier { 86 | FormCell *cell = nil; 87 | for (FormCell *reusableCell in _reusableCells) { 88 | if ([reusableCell.identifier isEqualToString:identifier]) { 89 | cell = reusableCell; 90 | break; 91 | } 92 | } 93 | if (cell) { 94 | [_reusableCells removeObject:cell]; 95 | } 96 | return cell; 97 | } 98 | - (FTopLeftHeaderView *)dequeueReusableTopLeftView { 99 | FTopLeftHeaderView *header = nil; 100 | for (FTopLeftHeaderView *reusableheader in _reusableTopLeftHeaders) { 101 | header = reusableheader; 102 | break; 103 | } 104 | if (header) { 105 | [_reusableTopLeftHeaders removeObject:header]; 106 | } 107 | return header; 108 | } 109 | 110 | /////que 111 | - (void)queueReusableCell:(FormCell *)cell { 112 | if (cell) { 113 | cell.indexPath = nil; 114 | [cell removeTarget:self action:@selector(cellClickAction:) forControlEvents:UIControlEventTouchUpInside]; 115 | [_reusableCells addObject:cell]; 116 | } 117 | } 118 | - (void)queueReusableColumnHeader:(FormColumnHeaderView *)columnHeader { 119 | if (columnHeader) { 120 | [columnHeader setColumn:-1]; 121 | [columnHeader removeTarget:self action:@selector(columnClickAction:) forControlEvents:UIControlEventTouchUpInside]; 122 | [_reusableColumnHeaders addObject:columnHeader]; 123 | } 124 | } 125 | - (void)queueReusableSectionHeader:(FormSectionHeaderView *)sectionHeader { 126 | if (sectionHeader){ 127 | [sectionHeader setSection:-1]; 128 | [sectionHeader removeTarget:self action:@selector(sectionClickAction:) forControlEvents:UIControlEventTouchUpInside]; 129 | [_reusableSectionsHeaders addObject:sectionHeader]; 130 | } 131 | } 132 | - (void)queueReusableTopLeftHeader:(FTopLeftHeaderView *)topLeftView { 133 | if (topLeftView) { 134 | [_reusableTopLeftHeaders addObject:topLeftView]; 135 | } 136 | } 137 | 138 | 139 | ////LoadView 140 | - (void)reloadData { 141 | if (!_fDataSource) { 142 | #if DEBUG 143 | NSLog(@"!!!!!!FormScrollView's fDataSource not set!!!!!!"); 144 | #endif 145 | return; 146 | } 147 | [[self subviews] enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop) { 148 | if ([obj isKindOfClass:[FormColumnHeaderView class]]) { 149 | [self queueReusableColumnHeader:(FormColumnHeaderView *)obj]; 150 | [(UIView *)obj removeFromSuperview]; 151 | } else if ([obj isKindOfClass:[FormSectionHeaderView class]]) { 152 | [self queueReusableSectionHeader:(FormSectionHeaderView *)obj]; 153 | [(UIView *)obj removeFromSuperview]; 154 | } else if ([obj isKindOfClass:[FormCell class]]) { 155 | [self queueReusableCell:(FormCell *)obj]; 156 | [(UIView *)obj removeFromSuperview]; 157 | } else if ([obj isKindOfClass:[FTopLeftHeaderView class]]){ 158 | [self queueReusableTopLeftHeader:(FTopLeftHeaderView *)obj]; 159 | [(UIView *)obj removeFromSuperview]; 160 | } else { 161 | [(UIView *)obj removeFromSuperview]; 162 | } 163 | }]; 164 | 165 | NSInteger numberSection = [_fDataSource numberOfSection:self]; 166 | _numberSection = numberSection; 167 | NSInteger numberColumn = [_fDataSource numberOfColumn:self]; 168 | _numberColumn = numberColumn; 169 | _width = [_fDataSource widthForColumn:self]; 170 | _height = [_fDataSource heightForSection:self]; 171 | self.contentSize = CGSizeMake((_numberColumn+1)*_width, (_numberSection+1)*_height); 172 | 173 | _topLeftView = [_fDataSource topLeftHeadViewForForm:self]; 174 | [self setNeedsLayout]; 175 | } 176 | 177 | - (void)layoutSubviews { 178 | [super layoutSubviews]; 179 | [self cleanupUnseenItems]; 180 | [self loadseenItems]; 181 | } 182 | 183 | - (void)loadseenItems { 184 | if (!_topLeftView.superview) { 185 | _topLeftView.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, _width, _height); 186 | [self.superview addSubview:_topLeftView]; 187 | } 188 | for (NSInteger section=0; section<_numberSection; section++) { 189 | if (section*_height>self.contentOffset.y+self.frame.size.height 190 | || (section+1)*_heightself.contentOffset.x+self.frame.size.width 195 | || (column+1)*_width=_firstIndexPath.column 199 | &&column<=_maxIndexPath.column 200 | &§ion>=_firstIndexPath.section 201 | &§ion<=_maxIndexPath.section) { 202 | continue; 203 | } 204 | CGRect rect = CGRectMake((column+1)*_width, (section+1)*_height, _width, _height); 205 | if ([self isOnScreenRect:rect]) { 206 | FIndexPath *indexPath = [FIndexPath indexPathForSection:section inColumn:column]; 207 | FormCell *cell = [_fDataSource form:self cellForColumnAtIndexPath:indexPath]; 208 | [cell addTarget:self action:@selector(cellClickAction:) forControlEvents:UIControlEventTouchUpInside]; 209 | cell.indexPath = indexPath; 210 | cell.frame = rect; 211 | [self insertSubview:cell atIndex:0]; 212 | } 213 | } 214 | } 215 | for (NSInteger section=0; section<_numberSection; section++) { 216 | if (section*_height>self.contentOffset.y+self.frame.size.height 217 | || (section+1)*_height=_firstIndexPath.section 221 | &§ion<=_maxIndexPath.section) { 222 | continue; 223 | } 224 | CGRect rect = CGRectMake(self.contentOffset.x+self.contentInset.left, (section+1)*_height, _width, _height); 225 | if ([self isOnScreenRect:rect]) { 226 | FormSectionHeaderView *header = [_fDataSource form:self sectionHeaderAtSection:section]; 227 | [header addTarget:self action:@selector(sectionClickAction:) forControlEvents:UIControlEventTouchUpInside]; 228 | header.frame = rect; 229 | [self addSubview:header]; 230 | } 231 | } 232 | for (NSInteger column=0; column<_numberColumn; column++) { 233 | if (column*_width>self.contentOffset.x+self.frame.size.width 234 | || (column+1)*_width=_firstIndexPath.column 238 | &&column<=_maxIndexPath.column) { 239 | continue; 240 | } 241 | CGRect rect = CGRectMake((column+1)*_width, self.contentOffset.y+self.contentInset.top, _width, _height); 242 | if ([self isOnScreenRect:rect]) { 243 | FormColumnHeaderView *header = [_fDataSource form:self columnHeaderAtColumn:column]; 244 | [header addTarget:self action:@selector(columnClickAction:) forControlEvents:UIControlEventTouchUpInside]; 245 | header.frame = rect; 246 | [self addSubview:header]; 247 | } 248 | } 249 | } 250 | 251 | 252 | ////Clear 253 | - (void)cleanupUnseenItems { 254 | _firstIndexPath = [FIndexPath indexPathForSection:_numberSection inColumn:_numberColumn]; 255 | _maxIndexPath = [FIndexPath indexPathForSection:0 inColumn:0]; 256 | for (UIView *view in self.subviews) { 257 | if (![self isOnScreenRect:view.frame]) { 258 | if ([view isKindOfClass:[FormCell class]]) { 259 | FormCell*cell = (FormCell *)view; 260 | [self queueReusableCell:cell]; 261 | [cell removeFromSuperview]; 262 | } else if ([view isKindOfClass:[FormSectionHeaderView class]]) { 263 | FormSectionHeaderView*header = (FormSectionHeaderView *)view; 264 | header.frame = CGRectMake(self.contentOffset.x+self.contentInset.left, CGRectGetMinY(header.frame), CGRectGetWidth(header.frame), CGRectGetHeight(header.frame)); 265 | if (![self isOnScreenRect:header.frame]) { 266 | [self queueReusableSectionHeader:header]; 267 | [header removeFromSuperview]; 268 | } 269 | } else if ([view isKindOfClass:[FormColumnHeaderView class]]) { 270 | FormColumnHeaderView*header = (FormColumnHeaderView *)view; 271 | header.frame = CGRectMake(CGRectGetMinX(header.frame), self.contentOffset.y+self.contentInset.top, CGRectGetWidth(header.frame), CGRectGetHeight(header.frame)); 272 | if (![self isOnScreenRect:header.frame]) { 273 | [self queueReusableColumnHeader:header]; 274 | [header removeFromSuperview]; 275 | } 276 | } 277 | } else { 278 | if ([view isKindOfClass:[FormSectionHeaderView class]]) { 279 | FormSectionHeaderView*header = (FormSectionHeaderView *)view; 280 | header.frame = CGRectMake(self.contentOffset.x+self.contentInset.left, CGRectGetMinY(header.frame), CGRectGetWidth(header.frame), CGRectGetHeight(header.frame)); 281 | } else if ([view isKindOfClass:[FormColumnHeaderView class]]) { 282 | FormColumnHeaderView*header = (FormColumnHeaderView *)view; 283 | header.frame = CGRectMake(CGRectGetMinX(header.frame), self.contentOffset.y+self.contentInset.top, CGRectGetWidth(header.frame), CGRectGetHeight(header.frame)); 284 | } else if ([view isKindOfClass:[FormCell class]]) { 285 | FormCell*cell = (FormCell *)view; 286 | if (cell.indexPath.section<=_firstIndexPath.section && cell.indexPath.column<=_firstIndexPath.column) { 287 | _firstIndexPath = [FIndexPath indexPathForSection:cell.indexPath.section inColumn:cell.indexPath.column]; 288 | } 289 | if (cell.indexPath.section>=_maxIndexPath.section && cell.indexPath.column>=_maxIndexPath.column) { 290 | _maxIndexPath = [FIndexPath indexPathForSection:cell.indexPath.section inColumn:cell.indexPath.column]; 291 | } 292 | } 293 | } 294 | } 295 | } 296 | - (BOOL)isOnScreenRect:(CGRect)rect { 297 | return CGRectIntersectsRect(rect, CGRectMake(self.contentOffset.x, self.contentOffset.y, self.frame.size.width, self.frame.size.height)); 298 | } 299 | 300 | - (void)cellClickAction:(FormCell *)cell { 301 | if (_fDelegate) { 302 | if ([_fDelegate respondsToSelector:@selector(form:didSelectCellAtIndexPath:)]) { 303 | [_fDelegate form:self didSelectCellAtIndexPath:cell.indexPath]; 304 | } 305 | } 306 | } 307 | - (void)columnClickAction:(FormColumnHeaderView *)columnView { 308 | if (_fDelegate) { 309 | if ([_fDelegate respondsToSelector:@selector(form:didSelectColumnAtIndex:)]) { 310 | [_fDelegate form:self didSelectColumnAtIndex:columnView.column]; 311 | } 312 | } 313 | } 314 | - (void)sectionClickAction:(FormSectionHeaderView *)sectionView { 315 | if (_fDelegate) { 316 | if ([_fDelegate respondsToSelector:@selector(form:didSelectSectionAtIndex:)]) { 317 | [_fDelegate form:self didSelectSectionAtIndex:sectionView.section]; 318 | } 319 | } 320 | } 321 | 322 | @end 323 | 324 | //// Cell 325 | @interface FormCell () 326 | @end 327 | @implementation FormCell 328 | - (instancetype)initWithIdentifier:(NSString *)identifier { 329 | self = [super init]; 330 | _identifier = [identifier copy]; 331 | self.backgroundColor = UIColor.whiteColor; 332 | return self; 333 | } 334 | - (void)setIndexPath:(FIndexPath *)indexPath { 335 | _indexPath = indexPath; 336 | } 337 | - (void)drawRect:(CGRect)rect { 338 | [super drawRect:rect]; 339 | CGContextRef context = UIGraphicsGetCurrentContext(); 340 | CGContextSetLineWidth(context, 1.0); 341 | CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); 342 | CGPoint aPoints[5]; 343 | aPoints[0] =CGPointMake(0, 0); 344 | aPoints[1] =CGPointMake(CGRectGetWidth(rect), 0); 345 | aPoints[2] =CGPointMake(CGRectGetWidth(rect), CGRectGetHeight(rect)); 346 | aPoints[3] =CGPointMake(0, CGRectGetHeight(rect)); 347 | aPoints[4] =CGPointMake(0, 0); 348 | CGContextAddLines(context, aPoints, 5); 349 | CGContextDrawPath(context, kCGPathStroke); 350 | } 351 | 352 | @end 353 | 354 | //// FormColumnHeaderView 355 | @interface FormColumnHeaderView () 356 | @end 357 | @implementation FormColumnHeaderView 358 | - (instancetype)initWithIdentifier:(NSString *)identifier { 359 | self = [super init]; 360 | _identifier = [identifier copy]; 361 | self.backgroundColor = UIColor.whiteColor; 362 | return self; 363 | } 364 | - (void)setColumn:(NSInteger)column { 365 | _column = column; 366 | } 367 | - (void)drawRect:(CGRect)rect { 368 | [super drawRect:rect]; 369 | CGContextRef context = UIGraphicsGetCurrentContext(); 370 | CGContextSetLineWidth(context, 1.0); 371 | CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); 372 | CGPoint aPoints[5]; 373 | aPoints[0] =CGPointMake(0, 0); 374 | aPoints[1] =CGPointMake(CGRectGetWidth(rect), 0); 375 | aPoints[2] =CGPointMake(CGRectGetWidth(rect), CGRectGetHeight(rect)); 376 | aPoints[3] =CGPointMake(0, CGRectGetHeight(rect)); 377 | aPoints[4] =CGPointMake(0, 0); 378 | CGContextAddLines(context, aPoints, 5); 379 | CGContextDrawPath(context, kCGPathStroke); 380 | } 381 | @end 382 | 383 | //// FormRowHeaderView 384 | @interface FormSectionHeaderView () 385 | @end 386 | @implementation FormSectionHeaderView 387 | - (instancetype)initWithIdentifier:(NSString *)identifier { 388 | self = [super init]; 389 | _identifier = [identifier copy]; 390 | self.backgroundColor = UIColor.whiteColor; 391 | return self; 392 | } 393 | - (void)setSection:(NSInteger)section { 394 | _section = section; 395 | } 396 | - (void)drawRect:(CGRect)rect { 397 | [super drawRect:rect]; 398 | CGContextRef context = UIGraphicsGetCurrentContext(); 399 | CGContextSetLineWidth(context, 1.0); 400 | CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); 401 | CGPoint aPoints[5]; 402 | aPoints[0] =CGPointMake(0, 0); 403 | aPoints[1] =CGPointMake(CGRectGetWidth(rect), 0); 404 | aPoints[2] =CGPointMake(CGRectGetWidth(rect), CGRectGetHeight(rect)); 405 | aPoints[3] =CGPointMake(0, CGRectGetHeight(rect)); 406 | aPoints[4] =CGPointMake(0, 0); 407 | CGContextAddLines(context, aPoints, 5); 408 | CGContextDrawPath(context, kCGPathStroke); 409 | } 410 | 411 | @end 412 | 413 | //// FTopLeftHeaderView 414 | @interface FTopLeftHeaderView() 415 | @end 416 | @implementation FTopLeftHeaderView 417 | 418 | - (instancetype)initWithSectionTitle:(NSString *)sectionTitle columnTitle:(NSString *)columnTitle { 419 | self = [super init]; 420 | _sectionTitle = sectionTitle; 421 | _columnTitle = columnTitle; 422 | return self; 423 | } 424 | - (void)drawRect:(CGRect)rect { 425 | CGContextRef context = UIGraphicsGetCurrentContext(); 426 | CGContextAddRect(context, rect); 427 | CGContextSetFillColorWithColor(context, [UIColor whiteColor].CGColor); 428 | CGContextDrawPath(context, kCGPathFill); 429 | CGContextStrokePath(context); 430 | NSMutableParagraphStyle *style = [[NSMutableParagraphStyle alloc] init]; 431 | style.alignment = NSTextAlignmentCenter; 432 | NSDictionary *attributrs = @{NSForegroundColorAttributeName:UIColor.blackColor, NSFontAttributeName:[UIFont systemFontOfSize:17], NSParagraphStyleAttributeName:style}; 433 | if (_columnTitle) { 434 | [_columnTitle drawInRect:CGRectMake(CGRectGetWidth(rect)/2, 0, CGRectGetWidth(rect)/2, CGRectGetHeight(rect)/2) withAttributes:attributrs]; 435 | CGContextStrokePath(context); 436 | } 437 | if (_sectionTitle) { 438 | [_sectionTitle drawInRect:CGRectMake(0, CGRectGetHeight(rect)/2, CGRectGetWidth(rect)/2, CGRectGetHeight(rect)/2) withAttributes:attributrs]; 439 | } 440 | CGContextSetLineWidth(context, 1.0); 441 | CGContextSetStrokeColorWithColor(context, [UIColor blackColor].CGColor); 442 | CGPoint aPoints[6]; 443 | aPoints[0] =CGPointMake(0, 0); 444 | aPoints[1] =CGPointMake(CGRectGetWidth(rect), 0); 445 | aPoints[2] =CGPointMake(CGRectGetWidth(rect), CGRectGetHeight(rect)); 446 | aPoints[3] =CGPointMake(0, 0); 447 | aPoints[4] =CGPointMake(0, CGRectGetHeight(rect)); 448 | aPoints[5] =CGPointMake(CGRectGetWidth(rect), CGRectGetHeight(rect)); 449 | CGContextAddLines(context, aPoints, 6); 450 | CGContextDrawPath(context, kCGPathStroke); 451 | } 452 | @end 453 | 454 | 455 | //// IndexPath 456 | @interface FIndexPath () 457 | @end 458 | @implementation FIndexPath 459 | + (instancetype)indexPathForSection:(NSInteger)section inColumn:(NSInteger)column { 460 | FIndexPath *indexPath = [[FIndexPath alloc] init]; 461 | indexPath.section = section; 462 | indexPath.column = column; 463 | return indexPath; 464 | } 465 | @end 466 | -------------------------------------------------------------------------------- /WhdeForm/WhdeForm/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /WhdeForm/WhdeForm/WhdeForm.h: -------------------------------------------------------------------------------- 1 | // 2 | // WhdeForm.h 3 | // WhdeForm 4 | // 5 | // Created by whde on 16/5/5. 6 | // Copyright © 2016年 whde. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | //! Project version number for WhdeForm. 12 | FOUNDATION_EXPORT double WhdeFormVersionNumber; 13 | 14 | //! Project version string for WhdeForm. 15 | FOUNDATION_EXPORT const unsigned char WhdeFormVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | F88601E81CDB55930044AB21 /* FormScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = F88601E61CDB55930044AB21 /* FormScrollView.m */; }; 11 | F888FC791CD9A5F500D1099E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F888FC781CD9A5F500D1099E /* main.m */; }; 12 | F888FC7C1CD9A5F500D1099E /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F888FC7B1CD9A5F500D1099E /* AppDelegate.m */; }; 13 | F888FC7F1CD9A5F500D1099E /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F888FC7E1CD9A5F500D1099E /* ViewController.m */; }; 14 | F888FC821CD9A5F500D1099E /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F888FC801CD9A5F500D1099E /* Main.storyboard */; }; 15 | F888FC841CD9A5F500D1099E /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F888FC831CD9A5F500D1099E /* Assets.xcassets */; }; 16 | F888FC941CD9DA1B00D1099E /* datas.plist in Resources */ = {isa = PBXBuildFile; fileRef = F888FC931CD9DA1B00D1099E /* datas.plist */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXFileReference section */ 20 | F88601E51CDB55930044AB21 /* FormScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormScrollView.h; sourceTree = ""; }; 21 | F88601E61CDB55930044AB21 /* FormScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FormScrollView.m; sourceTree = ""; }; 22 | F888FC741CD9A5F500D1099E /* WhdeFormDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WhdeFormDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 23 | F888FC781CD9A5F500D1099E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 24 | F888FC7A1CD9A5F500D1099E /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 25 | F888FC7B1CD9A5F500D1099E /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 26 | F888FC7D1CD9A5F500D1099E /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 27 | F888FC7E1CD9A5F500D1099E /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 28 | F888FC811CD9A5F500D1099E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 29 | F888FC831CD9A5F500D1099E /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 30 | F888FC881CD9A5F500D1099E /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 31 | F888FC931CD9DA1B00D1099E /* datas.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = datas.plist; sourceTree = ""; }; 32 | /* End PBXFileReference section */ 33 | 34 | /* Begin PBXFrameworksBuildPhase section */ 35 | F888FC711CD9A5F500D1099E /* Frameworks */ = { 36 | isa = PBXFrameworksBuildPhase; 37 | buildActionMask = 2147483647; 38 | files = ( 39 | ); 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | /* End PBXFrameworksBuildPhase section */ 43 | 44 | /* Begin PBXGroup section */ 45 | F88601E41CDB55930044AB21 /* Class */ = { 46 | isa = PBXGroup; 47 | children = ( 48 | F88601E51CDB55930044AB21 /* FormScrollView.h */, 49 | F88601E61CDB55930044AB21 /* FormScrollView.m */, 50 | ); 51 | name = Class; 52 | path = ../../WhdeForm/WhdeForm/Class; 53 | sourceTree = ""; 54 | }; 55 | F888FC6B1CD9A5F500D1099E = { 56 | isa = PBXGroup; 57 | children = ( 58 | F888FC761CD9A5F500D1099E /* WhdeFormDemo */, 59 | F888FC751CD9A5F500D1099E /* Products */, 60 | ); 61 | sourceTree = ""; 62 | }; 63 | F888FC751CD9A5F500D1099E /* Products */ = { 64 | isa = PBXGroup; 65 | children = ( 66 | F888FC741CD9A5F500D1099E /* WhdeFormDemo.app */, 67 | ); 68 | name = Products; 69 | sourceTree = ""; 70 | }; 71 | F888FC761CD9A5F500D1099E /* WhdeFormDemo */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | F88601E41CDB55930044AB21 /* Class */, 75 | F888FC7A1CD9A5F500D1099E /* AppDelegate.h */, 76 | F888FC7B1CD9A5F500D1099E /* AppDelegate.m */, 77 | F888FC931CD9DA1B00D1099E /* datas.plist */, 78 | F888FC7D1CD9A5F500D1099E /* ViewController.h */, 79 | F888FC7E1CD9A5F500D1099E /* ViewController.m */, 80 | F888FC801CD9A5F500D1099E /* Main.storyboard */, 81 | F888FC831CD9A5F500D1099E /* Assets.xcassets */, 82 | F888FC881CD9A5F500D1099E /* Info.plist */, 83 | F888FC771CD9A5F500D1099E /* Supporting Files */, 84 | ); 85 | path = WhdeFormDemo; 86 | sourceTree = ""; 87 | }; 88 | F888FC771CD9A5F500D1099E /* Supporting Files */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | F888FC781CD9A5F500D1099E /* main.m */, 92 | ); 93 | name = "Supporting Files"; 94 | sourceTree = ""; 95 | }; 96 | /* End PBXGroup section */ 97 | 98 | /* Begin PBXNativeTarget section */ 99 | F888FC731CD9A5F500D1099E /* WhdeFormDemo */ = { 100 | isa = PBXNativeTarget; 101 | buildConfigurationList = F888FC8B1CD9A5F500D1099E /* Build configuration list for PBXNativeTarget "WhdeFormDemo" */; 102 | buildPhases = ( 103 | F888FC701CD9A5F500D1099E /* Sources */, 104 | F888FC711CD9A5F500D1099E /* Frameworks */, 105 | F888FC721CD9A5F500D1099E /* Resources */, 106 | ); 107 | buildRules = ( 108 | ); 109 | dependencies = ( 110 | ); 111 | name = WhdeFormDemo; 112 | productName = WhdeFormDemo; 113 | productReference = F888FC741CD9A5F500D1099E /* WhdeFormDemo.app */; 114 | productType = "com.apple.product-type.application"; 115 | }; 116 | /* End PBXNativeTarget section */ 117 | 118 | /* Begin PBXProject section */ 119 | F888FC6C1CD9A5F500D1099E /* Project object */ = { 120 | isa = PBXProject; 121 | attributes = { 122 | LastUpgradeCheck = 0730; 123 | ORGANIZATIONNAME = whde; 124 | TargetAttributes = { 125 | F888FC731CD9A5F500D1099E = { 126 | CreatedOnToolsVersion = 7.3; 127 | }; 128 | }; 129 | }; 130 | buildConfigurationList = F888FC6F1CD9A5F500D1099E /* Build configuration list for PBXProject "WhdeFormDemo" */; 131 | compatibilityVersion = "Xcode 3.2"; 132 | developmentRegion = English; 133 | hasScannedForEncodings = 0; 134 | knownRegions = ( 135 | en, 136 | Base, 137 | ); 138 | mainGroup = F888FC6B1CD9A5F500D1099E; 139 | productRefGroup = F888FC751CD9A5F500D1099E /* Products */; 140 | projectDirPath = ""; 141 | projectRoot = ""; 142 | targets = ( 143 | F888FC731CD9A5F500D1099E /* WhdeFormDemo */, 144 | ); 145 | }; 146 | /* End PBXProject section */ 147 | 148 | /* Begin PBXResourcesBuildPhase section */ 149 | F888FC721CD9A5F500D1099E /* Resources */ = { 150 | isa = PBXResourcesBuildPhase; 151 | buildActionMask = 2147483647; 152 | files = ( 153 | F888FC841CD9A5F500D1099E /* Assets.xcassets in Resources */, 154 | F888FC941CD9DA1B00D1099E /* datas.plist in Resources */, 155 | F888FC821CD9A5F500D1099E /* Main.storyboard in Resources */, 156 | ); 157 | runOnlyForDeploymentPostprocessing = 0; 158 | }; 159 | /* End PBXResourcesBuildPhase section */ 160 | 161 | /* Begin PBXSourcesBuildPhase section */ 162 | F888FC701CD9A5F500D1099E /* Sources */ = { 163 | isa = PBXSourcesBuildPhase; 164 | buildActionMask = 2147483647; 165 | files = ( 166 | F888FC7F1CD9A5F500D1099E /* ViewController.m in Sources */, 167 | F88601E81CDB55930044AB21 /* FormScrollView.m in Sources */, 168 | F888FC7C1CD9A5F500D1099E /* AppDelegate.m in Sources */, 169 | F888FC791CD9A5F500D1099E /* main.m in Sources */, 170 | ); 171 | runOnlyForDeploymentPostprocessing = 0; 172 | }; 173 | /* End PBXSourcesBuildPhase section */ 174 | 175 | /* Begin PBXVariantGroup section */ 176 | F888FC801CD9A5F500D1099E /* Main.storyboard */ = { 177 | isa = PBXVariantGroup; 178 | children = ( 179 | F888FC811CD9A5F500D1099E /* Base */, 180 | ); 181 | name = Main.storyboard; 182 | sourceTree = ""; 183 | }; 184 | /* End PBXVariantGroup section */ 185 | 186 | /* Begin XCBuildConfiguration section */ 187 | F888FC891CD9A5F500D1099E /* Debug */ = { 188 | isa = XCBuildConfiguration; 189 | buildSettings = { 190 | ALWAYS_SEARCH_USER_PATHS = NO; 191 | CLANG_ANALYZER_NONNULL = YES; 192 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 193 | CLANG_CXX_LIBRARY = "libc++"; 194 | CLANG_ENABLE_MODULES = YES; 195 | CLANG_ENABLE_OBJC_ARC = YES; 196 | CLANG_WARN_BOOL_CONVERSION = YES; 197 | CLANG_WARN_CONSTANT_CONVERSION = YES; 198 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 199 | CLANG_WARN_EMPTY_BODY = YES; 200 | CLANG_WARN_ENUM_CONVERSION = YES; 201 | CLANG_WARN_INT_CONVERSION = YES; 202 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 203 | CLANG_WARN_UNREACHABLE_CODE = YES; 204 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 205 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 206 | COPY_PHASE_STRIP = NO; 207 | DEBUG_INFORMATION_FORMAT = dwarf; 208 | ENABLE_STRICT_OBJC_MSGSEND = YES; 209 | ENABLE_TESTABILITY = YES; 210 | GCC_C_LANGUAGE_STANDARD = gnu99; 211 | GCC_DYNAMIC_NO_PIC = NO; 212 | GCC_NO_COMMON_BLOCKS = YES; 213 | GCC_OPTIMIZATION_LEVEL = 0; 214 | GCC_PREPROCESSOR_DEFINITIONS = ( 215 | "DEBUG=1", 216 | "$(inherited)", 217 | ); 218 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 219 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 220 | GCC_WARN_UNDECLARED_SELECTOR = YES; 221 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 222 | GCC_WARN_UNUSED_FUNCTION = YES; 223 | GCC_WARN_UNUSED_VARIABLE = YES; 224 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 225 | MTL_ENABLE_DEBUG_INFO = YES; 226 | ONLY_ACTIVE_ARCH = YES; 227 | SDKROOT = iphoneos; 228 | }; 229 | name = Debug; 230 | }; 231 | F888FC8A1CD9A5F500D1099E /* Release */ = { 232 | isa = XCBuildConfiguration; 233 | buildSettings = { 234 | ALWAYS_SEARCH_USER_PATHS = NO; 235 | CLANG_ANALYZER_NONNULL = YES; 236 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 237 | CLANG_CXX_LIBRARY = "libc++"; 238 | CLANG_ENABLE_MODULES = YES; 239 | CLANG_ENABLE_OBJC_ARC = YES; 240 | CLANG_WARN_BOOL_CONVERSION = YES; 241 | CLANG_WARN_CONSTANT_CONVERSION = YES; 242 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 243 | CLANG_WARN_EMPTY_BODY = YES; 244 | CLANG_WARN_ENUM_CONVERSION = YES; 245 | CLANG_WARN_INT_CONVERSION = YES; 246 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 247 | CLANG_WARN_UNREACHABLE_CODE = YES; 248 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 249 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 250 | COPY_PHASE_STRIP = NO; 251 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 252 | ENABLE_NS_ASSERTIONS = NO; 253 | ENABLE_STRICT_OBJC_MSGSEND = YES; 254 | GCC_C_LANGUAGE_STANDARD = gnu99; 255 | GCC_NO_COMMON_BLOCKS = YES; 256 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 257 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 258 | GCC_WARN_UNDECLARED_SELECTOR = YES; 259 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 260 | GCC_WARN_UNUSED_FUNCTION = YES; 261 | GCC_WARN_UNUSED_VARIABLE = YES; 262 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 263 | MTL_ENABLE_DEBUG_INFO = NO; 264 | SDKROOT = iphoneos; 265 | VALIDATE_PRODUCT = YES; 266 | }; 267 | name = Release; 268 | }; 269 | F888FC8C1CD9A5F500D1099E /* Debug */ = { 270 | isa = XCBuildConfiguration; 271 | buildSettings = { 272 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 273 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 274 | INFOPLIST_FILE = WhdeFormDemo/Info.plist; 275 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 276 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 277 | PRODUCT_BUNDLE_IDENTIFIER = com.ziyoubang.WhdeFormDemo; 278 | PRODUCT_NAME = "$(TARGET_NAME)"; 279 | TARGETED_DEVICE_FAMILY = "1,2"; 280 | }; 281 | name = Debug; 282 | }; 283 | F888FC8D1CD9A5F500D1099E /* Release */ = { 284 | isa = XCBuildConfiguration; 285 | buildSettings = { 286 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 287 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 288 | INFOPLIST_FILE = WhdeFormDemo/Info.plist; 289 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 290 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 291 | PRODUCT_BUNDLE_IDENTIFIER = com.ziyoubang.WhdeFormDemo; 292 | PRODUCT_NAME = "$(TARGET_NAME)"; 293 | TARGETED_DEVICE_FAMILY = "1,2"; 294 | }; 295 | name = Release; 296 | }; 297 | /* End XCBuildConfiguration section */ 298 | 299 | /* Begin XCConfigurationList section */ 300 | F888FC6F1CD9A5F500D1099E /* Build configuration list for PBXProject "WhdeFormDemo" */ = { 301 | isa = XCConfigurationList; 302 | buildConfigurations = ( 303 | F888FC891CD9A5F500D1099E /* Debug */, 304 | F888FC8A1CD9A5F500D1099E /* Release */, 305 | ); 306 | defaultConfigurationIsVisible = 0; 307 | defaultConfigurationName = Release; 308 | }; 309 | F888FC8B1CD9A5F500D1099E /* Build configuration list for PBXNativeTarget "WhdeFormDemo" */ = { 310 | isa = XCConfigurationList; 311 | buildConfigurations = ( 312 | F888FC8C1CD9A5F500D1099E /* Debug */, 313 | F888FC8D1CD9A5F500D1099E /* Release */, 314 | ); 315 | defaultConfigurationIsVisible = 0; 316 | defaultConfigurationName = Release; 317 | }; 318 | /* End XCConfigurationList section */ 319 | }; 320 | rootObject = F888FC6C1CD9A5F500D1099E /* Project object */; 321 | } 322 | -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo.xcodeproj/project.xcworkspace/xcuserdata/OS.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo.xcodeproj/project.xcworkspace/xcuserdata/OS.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo.xcodeproj/project.xcworkspace/xcuserdata/whde.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo.xcodeproj/project.xcworkspace/xcuserdata/whde.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo.xcodeproj/xcuserdata/OS.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WhdeFormDemo.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo.xcodeproj/xcuserdata/whde.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo.xcodeproj/xcuserdata/whde.xcuserdatad/xcschemes/WhdeFormDemo.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 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo.xcodeproj/xcuserdata/whde.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | WhdeFormDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | F888FC731CD9A5F500D1099E 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // WhdeFormDemo 4 | // 5 | // Created by whde on 16/5/4. 6 | // Copyright © 2016年 whde. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // WhdeFormDemo 4 | // 5 | // Created by whde on 16/5/4. 6 | // Copyright © 2016年 whde. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | - (void)applicationWillResignActive:(UIApplication *)application { 24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 26 | } 27 | 28 | - (void)applicationDidEnterBackground:(UIApplication *)application { 29 | // 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. 30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 31 | } 32 | 33 | - (void)applicationWillEnterForeground:(UIApplication *)application { 34 | // 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. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application { 42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "29x29", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-29.0@1x.png", 7 | "scale" : "1x" 8 | }, 9 | { 10 | "size" : "29x29", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-29.0@2x.png", 13 | "scale" : "2x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-29.0@3x.png", 19 | "scale" : "3x" 20 | }, 21 | { 22 | "size" : "40x40", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-40.0@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-40.0@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "57x57", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-57.0@1x.png", 37 | "scale" : "1x" 38 | }, 39 | { 40 | "size" : "57x57", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-57.0@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-60.0@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-60.0@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "29x29", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-29.0@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-29.0@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "40x40", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-40.0@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-40.0@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "50x50", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-50.0@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "50x50", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-50.0@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "72x72", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-72.0@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "72x72", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-72.0@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "76x76", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-76.0@1x.png", 109 | "scale" : "1x" 110 | }, 111 | { 112 | "size" : "76x76", 113 | "idiom" : "ipad", 114 | "filename" : "Icon-76.0@2x.png", 115 | "scale" : "2x" 116 | }, 117 | { 118 | "size" : "83.5x83.5", 119 | "idiom" : "ipad", 120 | "filename" : "Icon-83.5@2x.png", 121 | "scale" : "2x" 122 | } 123 | ], 124 | "info" : { 125 | "version" : 1, 126 | "author" : "xcode" 127 | } 128 | } -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-29.0@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-29.0@1x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-29.0@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-29.0@2x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-29.0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-29.0@3x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-40.0@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-40.0@1x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-40.0@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-40.0@2x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-40.0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-40.0@3x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-50.0@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-50.0@1x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-50.0@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-50.0@2x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-57.0@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-57.0@1x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-57.0@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-57.0@2x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-60.0@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-60.0@2x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-60.0@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-60.0@3x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-72.0@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-72.0@1x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-72.0@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-72.0@2x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-76.0@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-76.0@1x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-76.0@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-76.0@2x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whde/WhdeForm/cc7320cc8a01e22064bd738b255f014d03d60226/WhdeFormDemo/WhdeFormDemo/Assets.xcassets/AppIcon.appiconset/Icon-83.5@2x.png -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Base.lproj/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 | -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | WhdeForm 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UIRequiresFullScreen 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // WhdeFormDemo 4 | // 5 | // Created by whde on 16/5/4. 6 | // Copyright © 2016年 whde. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // WhdeFormDemo 4 | // 5 | // Created by whde on 16/5/4. 6 | // Copyright © 2016年 whde. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "FormScrollView.h" 11 | @interface ViewController () { 12 | NSArray *_data; 13 | } 14 | 15 | @end 16 | 17 | @implementation ViewController 18 | 19 | - (void)viewDidLoad { 20 | [super viewDidLoad]; 21 | self.edgesForExtendedLayout = UIRectEdgeNone; 22 | self.view.autoresizingMask = UIViewAutoresizingNone; 23 | FormScrollView *table = [[FormScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height-64)]; 24 | table.contentInset = UIEdgeInsetsMake(0, 0, 0, 0); 25 | table.fDelegate = self; 26 | table.fDataSource = self; 27 | [self.view addSubview:table]; 28 | 29 | _data = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"datas" ofType:@"plist"]]; 30 | [table reloadData]; 31 | } 32 | - (FTopLeftHeaderView *)topLeftHeadViewForForm:(FormScrollView *)formScrollView { 33 | FTopLeftHeaderView *view = [formScrollView dequeueReusableTopLeftView]; 34 | if (view == NULL) { 35 | view = [[FTopLeftHeaderView alloc] initWithSectionTitle:@"行数" columnTitle:@"列数"]; 36 | } 37 | return view; 38 | } 39 | 40 | - (NSInteger)numberOfSection:(FormScrollView *)formScrollView { 41 | return _data.count; 42 | } 43 | - (NSInteger)numberOfColumn:(FormScrollView *)formScrollView { 44 | return 100; 45 | } 46 | - (CGFloat)heightForSection:(FormScrollView *)formScrollView { 47 | return 44; 48 | } 49 | - (CGFloat)widthForColumn:(FormScrollView *)formScrollView { 50 | return 80; 51 | } 52 | - (FormSectionHeaderView *)form:(FormScrollView *)formScrollView sectionHeaderAtSection:(NSInteger)section { 53 | FormSectionHeaderView *header = [formScrollView dequeueReusableSectionWithIdentifier:@"Section"]; 54 | if (header == NULL) { 55 | header = [[FormSectionHeaderView alloc] initWithIdentifier:@"Section"]; 56 | } 57 | [header setTitle:[NSString stringWithFormat:@"第%ld行", (long)section] forState:UIControlStateNormal]; 58 | [header setBackgroundColor:[UIColor redColor]]; 59 | [header setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 60 | return header; 61 | } 62 | - (FormColumnHeaderView *)form:(FormScrollView *)formScrollView columnHeaderAtColumn:(NSInteger)column { 63 | FormColumnHeaderView *header = [formScrollView dequeueReusableColumnWithIdentifier:@"Column"]; 64 | if (header == NULL) { 65 | header = [[FormColumnHeaderView alloc] initWithIdentifier:@"Column"]; 66 | } 67 | [header setTitle:[NSString stringWithFormat:@"第%ld列", (long)column] forState:UIControlStateNormal]; 68 | [header setBackgroundColor:[UIColor greenColor]]; 69 | [header setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 70 | return header; 71 | } 72 | - (FormCell *)form:(FormScrollView *)formScrollView cellForColumnAtIndexPath:(FIndexPath *)indexPath { 73 | FormCell *cell = [formScrollView dequeueReusableCellWithIdentifier:@"Cell"]; 74 | NSLog(@"%@", cell); 75 | if (cell == NULL) { 76 | cell = [[FormCell alloc] initWithIdentifier:@"Cell"]; 77 | static int i=0; 78 | i++; 79 | NSLog(@"%d--%ld", i, (long)indexPath.section); 80 | } 81 | NSDictionary *dic = [_data objectAtIndex:indexPath.section]; 82 | [cell setTitle:dic[@"name"] forState:UIControlStateNormal]; 83 | [cell setTitleColor:[UIColor blueColor] forState:UIControlStateNormal]; 84 | /*[cell setBackgroundColor:[UIColor yellowColor]];*/ 85 | return cell; 86 | } 87 | - (void)form:(FormScrollView *)formScrollView didSelectSectionAtIndex:(NSInteger)section { 88 | NSLog(@"Click Section At Index:%ld", (long)section); 89 | } 90 | - (void)form:(FormScrollView *)formScrollView didSelectColumnAtIndex:(NSInteger)column { 91 | NSLog(@"Click Cloumn At Index:%ld", (long)column); 92 | } 93 | - (void)form:(FormScrollView *)formScrollView didSelectCellAtIndexPath:(FIndexPath *)indexPath { 94 | NSLog(@"Click Cell At IndexPath:%ld,%ld", (long)indexPath.section, (long)indexPath.column); 95 | } 96 | - (void)didReceiveMemoryWarning { 97 | [super didReceiveMemoryWarning]; 98 | } 99 | 100 | @end 101 | -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/datas.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | name 7 | 小红 8 | sex 9 | 10 | age 11 | 12 12 | 13 | 14 | name 15 | 小强 16 | sex 17 | 18 | age 19 | 14 20 | 21 | 22 | name 23 | 小李 24 | sex 25 | 26 | age 27 | 34 28 | 29 | 30 | name 31 | 老王 32 | sex 33 | 34 | age 35 | 56 36 | 37 | 38 | name 39 | 小杨 40 | sex 41 | 42 | age 43 | 24 44 | 45 | 46 | name 47 | 小陈 48 | sex 49 | 50 | age 51 | 15 52 | 53 | 54 | name 55 | 小明 56 | sex 57 | 58 | age 59 | 16 60 | 61 | 62 | name 63 | 小赵 64 | sex 65 | 66 | age 67 | 26 68 | 69 | 70 | name 71 | 小马 72 | sex 73 | 74 | age 75 | 25 76 | 77 | 78 | name 79 | 小路 80 | sex 81 | 82 | age 83 | 26 84 | 85 | 86 | name 87 | 小黄 88 | sex 89 | 90 | age 91 | 24 92 | 93 | 94 | name 95 | 李红 96 | sex 97 | 98 | age 99 | 21 100 | 101 | 102 | name 103 | 刘亮 104 | sex 105 | 106 | age 107 | 28 108 | 109 | 110 | name 111 | 黄莺 112 | sex 113 | 114 | age 115 | 22 116 | 117 | 118 | name 119 | 小董 120 | sex 121 | 122 | age 123 | 20 124 | 125 | 126 | name 127 | 董卿 128 | sex 129 | 130 | age 131 | 37 132 | 133 | 134 | name 135 | 姚明 136 | sex 137 | 138 | age 139 | 40 140 | 141 | 142 | name 143 | 陈浩 144 | sex 145 | 146 | age 147 | 23 148 | 149 | 150 | name 151 | 董杰 152 | sex 153 | 154 | age 155 | 27 156 | 157 | 158 | name 159 | 陈明 160 | sex 161 | 162 | age 163 | 21 164 | 165 | 166 | name 167 | 小红 168 | sex 169 | 170 | age 171 | 12 172 | 173 | 174 | name 175 | 小强 176 | sex 177 | 178 | age 179 | 14 180 | 181 | 182 | name 183 | 小李 184 | sex 185 | 186 | age 187 | 34 188 | 189 | 190 | name 191 | 老王 192 | sex 193 | 194 | age 195 | 56 196 | 197 | 198 | name 199 | 小杨 200 | sex 201 | 202 | age 203 | 24 204 | 205 | 206 | name 207 | 小陈 208 | sex 209 | 210 | age 211 | 15 212 | 213 | 214 | name 215 | 小明 216 | sex 217 | 218 | age 219 | 16 220 | 221 | 222 | name 223 | 小赵 224 | sex 225 | 226 | age 227 | 26 228 | 229 | 230 | name 231 | 小马 232 | sex 233 | 234 | age 235 | 25 236 | 237 | 238 | name 239 | 小路 240 | sex 241 | 242 | age 243 | 26 244 | 245 | 246 | name 247 | 小黄 248 | sex 249 | 250 | age 251 | 24 252 | 253 | 254 | name 255 | 李红 256 | sex 257 | 258 | age 259 | 21 260 | 261 | 262 | name 263 | 刘亮 264 | sex 265 | 266 | age 267 | 28 268 | 269 | 270 | name 271 | 黄莺 272 | sex 273 | 274 | age 275 | 22 276 | 277 | 278 | name 279 | 小董 280 | sex 281 | 282 | age 283 | 20 284 | 285 | 286 | name 287 | 董卿 288 | sex 289 | 290 | age 291 | 37 292 | 293 | 294 | name 295 | 姚明 296 | sex 297 | 298 | age 299 | 40 300 | 301 | 302 | name 303 | 陈浩 304 | sex 305 | 306 | age 307 | 23 308 | 309 | 310 | name 311 | 董杰 312 | sex 313 | 314 | age 315 | 27 316 | 317 | 318 | name 319 | 陈明 320 | sex 321 | 322 | age 323 | 21 324 | 325 | 326 | name 327 | 小红 328 | sex 329 | 330 | age 331 | 12 332 | 333 | 334 | name 335 | 小强 336 | sex 337 | 338 | age 339 | 14 340 | 341 | 342 | name 343 | 小李 344 | sex 345 | 346 | age 347 | 34 348 | 349 | 350 | name 351 | 老王 352 | sex 353 | 354 | age 355 | 56 356 | 357 | 358 | name 359 | 小杨 360 | sex 361 | 362 | age 363 | 24 364 | 365 | 366 | name 367 | 小陈 368 | sex 369 | 370 | age 371 | 15 372 | 373 | 374 | name 375 | 小明 376 | sex 377 | 378 | age 379 | 16 380 | 381 | 382 | name 383 | 小赵 384 | sex 385 | 386 | age 387 | 26 388 | 389 | 390 | name 391 | 小马 392 | sex 393 | 394 | age 395 | 25 396 | 397 | 398 | name 399 | 小路 400 | sex 401 | 402 | age 403 | 26 404 | 405 | 406 | name 407 | 小黄 408 | sex 409 | 410 | age 411 | 24 412 | 413 | 414 | name 415 | 李红 416 | sex 417 | 418 | age 419 | 21 420 | 421 | 422 | name 423 | 刘亮 424 | sex 425 | 426 | age 427 | 28 428 | 429 | 430 | name 431 | 黄莺 432 | sex 433 | 434 | age 435 | 22 436 | 437 | 438 | name 439 | 小董 440 | sex 441 | 442 | age 443 | 20 444 | 445 | 446 | name 447 | 董卿 448 | sex 449 | 450 | age 451 | 37 452 | 453 | 454 | name 455 | 姚明 456 | sex 457 | 458 | age 459 | 40 460 | 461 | 462 | name 463 | 陈浩 464 | sex 465 | 466 | age 467 | 23 468 | 469 | 470 | name 471 | 董杰 472 | sex 473 | 474 | age 475 | 27 476 | 477 | 478 | name 479 | 陈明 480 | sex 481 | 482 | age 483 | 21 484 | 485 | 486 | name 487 | 小红 488 | sex 489 | 490 | age 491 | 12 492 | 493 | 494 | name 495 | 小强 496 | sex 497 | 498 | age 499 | 14 500 | 501 | 502 | name 503 | 小李 504 | sex 505 | 506 | age 507 | 34 508 | 509 | 510 | name 511 | 老王 512 | sex 513 | 514 | age 515 | 56 516 | 517 | 518 | name 519 | 小杨 520 | sex 521 | 522 | age 523 | 24 524 | 525 | 526 | name 527 | 小陈 528 | sex 529 | 530 | age 531 | 15 532 | 533 | 534 | name 535 | 小明 536 | sex 537 | 538 | age 539 | 16 540 | 541 | 542 | name 543 | 小赵 544 | sex 545 | 546 | age 547 | 26 548 | 549 | 550 | name 551 | 小马 552 | sex 553 | 554 | age 555 | 25 556 | 557 | 558 | name 559 | 小路 560 | sex 561 | 562 | age 563 | 26 564 | 565 | 566 | name 567 | 小黄 568 | sex 569 | 570 | age 571 | 24 572 | 573 | 574 | name 575 | 李红 576 | sex 577 | 578 | age 579 | 21 580 | 581 | 582 | name 583 | 刘亮 584 | sex 585 | 586 | age 587 | 28 588 | 589 | 590 | name 591 | 黄莺 592 | sex 593 | 594 | age 595 | 22 596 | 597 | 598 | name 599 | 小董 600 | sex 601 | 602 | age 603 | 20 604 | 605 | 606 | name 607 | 董卿 608 | sex 609 | 610 | age 611 | 37 612 | 613 | 614 | name 615 | 姚明 616 | sex 617 | 618 | age 619 | 40 620 | 621 | 622 | name 623 | 陈浩 624 | sex 625 | 626 | age 627 | 23 628 | 629 | 630 | name 631 | 董杰 632 | sex 633 | 634 | age 635 | 27 636 | 637 | 638 | name 639 | 陈明 640 | sex 641 | 642 | age 643 | 21 644 | 645 | 646 | name 647 | 小红 648 | sex 649 | 650 | age 651 | 12 652 | 653 | 654 | name 655 | 小强 656 | sex 657 | 658 | age 659 | 14 660 | 661 | 662 | name 663 | 小李 664 | sex 665 | 666 | age 667 | 34 668 | 669 | 670 | name 671 | 老王 672 | sex 673 | 674 | age 675 | 56 676 | 677 | 678 | name 679 | 小杨 680 | sex 681 | 682 | age 683 | 24 684 | 685 | 686 | name 687 | 小陈 688 | sex 689 | 690 | age 691 | 15 692 | 693 | 694 | name 695 | 小明 696 | sex 697 | 698 | age 699 | 16 700 | 701 | 702 | name 703 | 小赵 704 | sex 705 | 706 | age 707 | 26 708 | 709 | 710 | name 711 | 小马 712 | sex 713 | 714 | age 715 | 25 716 | 717 | 718 | name 719 | 小路 720 | sex 721 | 722 | age 723 | 26 724 | 725 | 726 | name 727 | 小黄 728 | sex 729 | 730 | age 731 | 24 732 | 733 | 734 | name 735 | 李红 736 | sex 737 | 738 | age 739 | 21 740 | 741 | 742 | name 743 | 刘亮 744 | sex 745 | 746 | age 747 | 28 748 | 749 | 750 | name 751 | 黄莺 752 | sex 753 | 754 | age 755 | 22 756 | 757 | 758 | name 759 | 小董 760 | sex 761 | 762 | age 763 | 20 764 | 765 | 766 | name 767 | 董卿 768 | sex 769 | 770 | age 771 | 37 772 | 773 | 774 | name 775 | 姚明 776 | sex 777 | 778 | age 779 | 40 780 | 781 | 782 | name 783 | 陈浩 784 | sex 785 | 786 | age 787 | 23 788 | 789 | 790 | name 791 | 董杰 792 | sex 793 | 794 | age 795 | 27 796 | 797 | 798 | name 799 | 陈明 800 | sex 801 | 802 | age 803 | 21 804 | 805 | 806 | 807 | -------------------------------------------------------------------------------- /WhdeFormDemo/WhdeFormDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // WhdeFormDemo 4 | // 5 | // Created by whde on 16/5/4. 6 | // Copyright © 2016年 whde. 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 | --------------------------------------------------------------------------------