├── MC.gif ├── MCTableViewManagerExample ├── MCTableViewManagerExample.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── xcuserdata │ │ └── marcochen.xcuserdatad │ │ │ ├── xcschemes │ │ │ └── xcschememanagement.plist │ │ │ └── xcdebugger │ │ │ └── Breakpoints_v2.xcbkptlist │ └── project.pbxproj ├── MCTableViewManagerExample │ ├── View │ │ ├── BExampleCell.h │ │ ├── AExampleCell.h │ │ ├── CTableViewCell.h │ │ ├── AExampleCell.m │ │ ├── BExampleCell.m │ │ └── CTableViewCell.m │ ├── ViewController.h │ ├── Controller │ │ ├── FuncInitExampleController.h │ │ ├── InstanceExampleController.h │ │ ├── InstanceExampleController.m │ │ └── FuncInitExampleController.m │ ├── AppDelegate.h │ ├── main.m │ ├── Info.plist │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── AppDelegate.m │ └── ViewController.m └── MCTableViewManagerExampleTests │ ├── Info.plist │ └── MCTableViewManagerExampleTests.m ├── MCTableViewManager ├── MCBaseHeaderFooterDataModel.m ├── MCTableViewDelegate.h ├── MCBaseHeaderFooterDataModel.h ├── MCBaseDataModel.h ├── MCTableViewManager.h ├── MCBaseDataModel.m ├── MCTableViewDelegate.m └── MCTableViewManager.m ├── LICENSE ├── README的副本.md └── README.md /MC.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CZXBigBrother/MCTableViewManager/HEAD/MC.gif -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/View/BExampleCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // BExampleCell.h 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2017/10/27. 6 | // Copyright © 2017年 marco chen. All rights reserved. 7 | // 8 | 9 | #import "MCBaseDataModel.h" 10 | 11 | @interface BExampleCell : MCBaseDataModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2017/10/27. 6 | // Copyright © 2017年 marco chen. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/Controller/FuncInitExampleController.h: -------------------------------------------------------------------------------- 1 | // 2 | // FuncInitExampleController.h 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2018/8/3. 6 | // Copyright © 2018年 marco chen. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FuncInitExampleController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/Controller/InstanceExampleController.h: -------------------------------------------------------------------------------- 1 | // 2 | // InstanceExampleController.h 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2018/8/3. 6 | // Copyright © 2018年 marco chen. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface InstanceExampleController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2017/10/27. 6 | // Copyright © 2017年 marco chen. 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 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/View/AExampleCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // AExampleCell.h 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2017/10/27. 6 | // Copyright © 2017年 marco chen. All rights reserved. 7 | // 8 | 9 | #import "MCBaseDataModel.h" 10 | 11 | @interface AExampleCell : MCBaseDataModel 12 | + (instancetype)initWithModelWithData:(id)cellParam withAcitonParams:(id)acitonParams; 13 | @end 14 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/View/CTableViewCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // CTableViewCell.h 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2018/8/2. 6 | // Copyright © 2018年 marco chen. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface CTableViewCell : UITableViewCell 12 | + (instancetype)cellWithTableView:(UITableView *)tableView; 13 | - (void)setdata:(NSDictionary *)data; 14 | @end 15 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2017/10/27. 6 | // Copyright © 2017年 marco chen. 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 | -------------------------------------------------------------------------------- /MCTableViewManager/MCBaseHeaderFooterDataModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // MCBaseHeaderFooterDataModel.m 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2018/8/8. 6 | // Copyright © 2018年 marco chen. All rights reserved. 7 | // 8 | 9 | #import "MCBaseHeaderFooterDataModel.h" 10 | 11 | @implementation MCBaseHeaderFooterDataModel 12 | - (NSMutableArray *)items { 13 | if (_items == nil) { 14 | _items = [NSMutableArray array]; 15 | } 16 | return _items; 17 | } 18 | @end 19 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample.xcodeproj/xcuserdata/marcochen.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | MCTableViewManagerExample.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /MCTableViewManager/MCTableViewDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // MCTableViewDelegate.h 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2018/8/3. 6 | // Copyright © 2018年 marco chen. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface MCTableViewDelegate : NSObject 13 | @property (weak, nonatomic) id MCDelegate; 14 | @property (weak, nonatomic) id target; 15 | - (instancetype)initWithTarget:(id)target; 16 | - (void)updateDatas:(NSArray *)arr; 17 | - (void)addObjectsDatas:(NSArray *)arr; 18 | @end 19 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample.xcodeproj/xcuserdata/marcochen.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/View/AExampleCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // AExampleCell.m 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2017/10/27. 6 | // Copyright © 2017年 marco chen. All rights reserved. 7 | // 8 | 9 | #import "AExampleCell.h" 10 | 11 | @implementation AExampleCell 12 | 13 | + (instancetype)initWithModelWithData:(id)cellParam withAcitonParams:(id)acitonParams 14 | { 15 | AExampleCell * data = [[AExampleCell alloc]init]; 16 | data.MCItemCell = @"AExampleCell"; 17 | data.MCItemAction = @"AExampleAction:"; 18 | data.MCItemHeight = 50; 19 | data.MCItemCellParam = cellParam; 20 | data.MCItemActionParams = acitonParams; 21 | return data; 22 | } 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/View/BExampleCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // BExampleCell.m 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2017/10/27. 6 | // Copyright © 2017年 marco chen. All rights reserved. 7 | // 8 | 9 | #import "BExampleCell.h" 10 | 11 | @implementation BExampleCell 12 | + (instancetype)initWithModelWithData:(id)cellParam withAcitonParams:(id)acitonParams { 13 | BExampleCell * data = [[BExampleCell alloc]init]; 14 | data.MCItemCell = @"BExampleCell:"; 15 | // data.MCItemAction = @"BExampleAction:"; 16 | data.MCItemAction = @"BExampleActionMultiplicityParam:withBParam:"; 17 | data.MCItemHeight = 100; 18 | data.MCItemCellParam = cellParam; 19 | data.MCItemActionParams = acitonParams; 20 | return data; 21 | } 22 | @end 23 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExampleTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MCTableViewManager/MCBaseHeaderFooterDataModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // MCBaseHeaderFooterDataModel.h 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2018/8/8. 6 | // Copyright © 2018年 marco chen. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "MCBaseDataModel.h" 12 | 13 | @interface MCBaseHeaderFooterDataModel : NSObject 14 | #pragma mark - footer 相关属性 15 | /** 16 | cell的foot对象 17 | */ 18 | @property (strong, nonatomic) UITableViewHeaderFooterView *MCItemFooter; 19 | /** 20 | cell的Footer高度 21 | */ 22 | @property (assign, nonatomic) CGFloat MCItemFooterHeight; 23 | #pragma mark - header 相关属性 24 | /** 25 | cell的header对象 26 | */ 27 | @property (strong, nonatomic) UITableViewHeaderFooterView *MCItemHeader; 28 | /** 29 | cell的Header高度 30 | */ 31 | @property (assign, nonatomic) CGFloat MCItemHeaderHeight; 32 | 33 | @property (strong, nonatomic) NSMutableArray *items; 34 | 35 | 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Marco Chen 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/View/CTableViewCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // CTableViewCell.m 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2018/8/2. 6 | // Copyright © 2018年 marco chen. All rights reserved. 7 | // 8 | 9 | #import "CTableViewCell.h" 10 | 11 | @implementation CTableViewCell 12 | + (instancetype)cellWithTableView:(UITableView *)tableView { 13 | static NSString *ID = @"CTableViewCell"; 14 | CTableViewCell * cell = [tableView dequeueReusableCellWithIdentifier:ID]; 15 | if (cell == nil) { 16 | cell = [[CTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; 17 | [cell setSelectionStyle:UITableViewCellSelectionStyleNone]; 18 | } 19 | return cell; 20 | } 21 | - (void)awakeFromNib { 22 | [super awakeFromNib]; 23 | // Initialization code 24 | } 25 | 26 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated { 27 | [super setSelected:selected animated:animated]; 28 | 29 | // Configure the view for the selected state 30 | } 31 | - (void)setdata:(NSDictionary *)data { 32 | self.textLabel.text = [data valueForKey:@"testParam"]; 33 | NSLog(@"setdata = %@",data); 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExampleTests/MCTableViewManagerExampleTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // MCTableViewManagerExampleTests.m 3 | // MCTableViewManagerExampleTests 4 | // 5 | // Created by marco chen on 2018/8/2. 6 | // Copyright © 2018年 marco chen. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MCTableViewManagerExampleTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation MCTableViewManagerExampleTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /MCTableViewManager/MCBaseDataModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // MCBaseDataModel.h 3 | // MCTableView 4 | // 5 | // Created by marco chen on 2017/10/26. 6 | // Copyright © 2017年 marco chen. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface MCBaseDataModel : NSObject 13 | 14 | #pragma mark - cell相关属性 15 | /** 16 | cell的创建方法 17 | */ 18 | @property (strong, nonatomic) id MCItemCell; 19 | /** 20 | cell需要赋值的参数 注意:目前只支持一个参数或者nil,如果需要更多参数,可以使用NSDictionary,NSArray,NSSet或者自定义对象等 21 | */ 22 | @property (strong, nonatomic) id MCItemCellParam; 23 | /** 24 | cell setData方法 25 | */ 26 | @property (strong, nonatomic) id MCItemSetDataAction; 27 | /** 28 | cell的高度 29 | */ 30 | @property (assign, nonatomic) CGFloat MCItemHeight; 31 | #pragma mark - cell selected事件相关属性 32 | /** 33 | cell的点击selected事件,如果不需要事件,可以赋值为nil或者[nsnull null] 34 | */ 35 | @property (strong, nonatomic) id MCItemAction; 36 | /** 37 | cell selected事件需要的参数 注意:目前最多支持10个参数 38 | */ 39 | @property (strong, nonatomic) NSArray *MCItemActionParams; 40 | 41 | /** 42 | 一个创建cell的示例 43 | @param cellParam cell需要的参数 44 | @param acitonParams cell点击事件需要的参数 45 | @return cell对象 46 | */ 47 | + (instancetype)initWithModelWithData:(id)cellParam withAcitonParams:(id)acitonParams; 48 | @end 49 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIRequiredDeviceCapabilities 26 | 27 | armv7 28 | 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | 33 | UISupportedInterfaceOrientations~ipad 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationPortraitUpsideDown 37 | UIInterfaceOrientationLandscapeLeft 38 | UIInterfaceOrientationLandscapeRight 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /MCTableViewManager/MCTableViewManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // MCTableViewManager.h 3 | // MCTableView 4 | // 5 | // Created by marco chen on 2017/10/25. 6 | // Copyright © 2017年 marco chen. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface MCTableViewManager : NSObject 13 | /** 14 | 初始化 15 | 16 | @param data 数据队列 17 | */ 18 | - (instancetype)initWithDatas:(NSMutableArray *)data; 19 | 20 | /** 21 | 更新队列 22 | 23 | @param data 队列数据 24 | */ 25 | - (void)updateDatas:(NSMutableArray *)data; 26 | 27 | /** 28 | 返回cell 29 | 30 | @param indexPath 和系统返回的indexPath相同 31 | @param target 执行方法的对象 32 | @return 对象 33 | */ 34 | - (instancetype)MC_cellForRowAtIndexPath:(NSIndexPath *)indexPath withTarget:(id)target; 35 | 36 | /** 37 | 返回cell高度 38 | 39 | @param indexPath 和系统返回的indexPath相同 40 | @return 高度 41 | */ 42 | - (CGFloat)MC_cellheightForRowAtIndexPath:(NSIndexPath *)indexPath; 43 | 44 | /** 45 | 返回cell点击事件 46 | 47 | @param indexPath 和系统返回的indexPath相同 48 | @param target 执行方法的对象 49 | */ 50 | - (void)MC_didSelectRowAtIndexPath:(NSIndexPath *)indexPath withTarget:(id)target; 51 | 52 | /** 53 | 返回队列组数 54 | 55 | @return 返回队列组数 56 | */ 57 | - (NSInteger)MC_numberOfSectionsInTableView; 58 | 59 | /** 60 | 返回队列组中的个数 61 | 62 | @param section 组index 63 | @return 返回队列组中的个数 64 | */ 65 | - (NSInteger)MC_numberOfRowsInSection:(NSInteger)section; 66 | 67 | - (CGFloat)MC_heightForFooterInSection:(NSInteger)section; 68 | - (CGFloat)MC_heightForHeaderInSection:(NSInteger)section; 69 | 70 | - (UIView *)MC_viewForHeaderInSection:(NSInteger)section; 71 | - (UIView *)MC_viewForFooterInSection:(NSInteger)section; 72 | @end 73 | -------------------------------------------------------------------------------- /MCTableViewManager/MCBaseDataModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // MCBaseDataModel.m 3 | // MCTableView 4 | // 5 | // Created by marco chen on 2017/10/26. 6 | // Copyright © 2017年 marco chen. All rights reserved. 7 | // 8 | 9 | #import "MCBaseDataModel.h" 10 | 11 | @implementation MCBaseDataModel 12 | - (instancetype)init { 13 | self = [super init]; 14 | if (self) { 15 | self.MCItemCell = nil; 16 | self.MCItemAction = nil; 17 | self.MCItemHeight = 0; 18 | self.MCItemCellParam = nil; 19 | self.MCItemActionParams = nil; 20 | // self.MCItemHeaderHeight = FLT_MIN; 21 | // self.MCItemFooterHeight = FLT_MIN; 22 | } 23 | return self; 24 | } 25 | + (instancetype)initWithModelWithData:(id)cellParam withAcitonParams:(id)acitonParams { 26 | MCBaseDataModel * data = [[MCBaseDataModel alloc]init]; 27 | data.MCItemCell = nil; 28 | data.MCItemAction = nil; 29 | data.MCItemHeight = 0; 30 | data.MCItemCellParam = nil; 31 | data.MCItemActionParams = nil; 32 | // data.MCItemHeaderHeight = FLT_MIN; 33 | // data.MCItemFooterHeight = FLT_MIN; 34 | return data; 35 | } 36 | 37 | + (instancetype)initWithModelWithCell:(id)cell 38 | withAction:(id)action 39 | withActionParams:(id)actionParams 40 | withHeight:(CGFloat)height 41 | withParam:(id)param { 42 | MCBaseDataModel * data = [[MCBaseDataModel alloc]init]; 43 | data.MCItemCell = cell; 44 | data.MCItemAction = action; 45 | data.MCItemHeight = height; 46 | data.MCItemCellParam = param; 47 | data.MCItemActionParams = actionParams; 48 | return data; 49 | } 50 | @end 51 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/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 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/Base.lproj/LaunchScreen.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 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2017/10/27. 6 | // Copyright © 2017年 marco chen. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "ViewController.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | // Override point for customization after application launch. 21 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] ; 22 | self.window.backgroundColor = [UIColor whiteColor]; 23 | ViewController * main = [[ViewController alloc]init]; 24 | UINavigationController * nav = [[UINavigationController alloc]initWithRootViewController:main]; 25 | self.window.rootViewController = nav; 26 | [self.window makeKeyAndVisible]; 27 | return YES; 28 | 29 | } 30 | 31 | 32 | - (void)applicationWillResignActive:(UIApplication *)application { 33 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 34 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 35 | } 36 | 37 | 38 | - (void)applicationDidEnterBackground:(UIApplication *)application { 39 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 40 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 41 | } 42 | 43 | 44 | - (void)applicationWillEnterForeground:(UIApplication *)application { 45 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 46 | } 47 | 48 | 49 | - (void)applicationDidBecomeActive:(UIApplication *)application { 50 | // 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. 51 | } 52 | 53 | 54 | - (void)applicationWillTerminate:(UIApplication *)application { 55 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 56 | } 57 | 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /MCTableViewManager/MCTableViewDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // MCTableViewDelegate.m 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2018/8/3. 6 | // Copyright © 2018年 marco chen. All rights reserved. 7 | // 8 | 9 | #import "MCTableViewDelegate.h" 10 | #import "MCTableViewManager.h" 11 | 12 | @interface MCTableViewDelegate() 13 | @property (strong, nonatomic) MCTableViewManager *myManage; 14 | @property (nonatomic, strong) NSMutableArray *itemsArray; 15 | 16 | @end 17 | 18 | @implementation MCTableViewDelegate 19 | 20 | - (instancetype)initWithTarget:(id)target 21 | { 22 | self = [super init]; 23 | if (self) { 24 | self.myManage = [[MCTableViewManager alloc]init]; 25 | self.target = target; 26 | } 27 | return self; 28 | } 29 | - (NSMutableArray *)itemsArray { 30 | if (_itemsArray == nil) { 31 | _itemsArray = [NSMutableArray array]; 32 | } 33 | return _itemsArray; 34 | } 35 | - (void)updateDatas:(NSArray *)arr { 36 | self.itemsArray = [NSMutableArray arrayWithArray:arr]; 37 | [self.myManage updateDatas:self.itemsArray]; 38 | } 39 | - (void)addObjectsDatas:(NSArray *)arr { 40 | [self.itemsArray addObjectsFromArray:arr]; 41 | [self.myManage updateDatas:self.itemsArray]; 42 | } 43 | 44 | #pragma mark - UITableView Delegate 45 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 46 | if ([self.MCDelegate respondsToSelector:@selector(numberOfSectionsInTableView:)]) { 47 | return [self.MCDelegate numberOfSectionsInTableView:tableView]; 48 | } 49 | return [self.myManage MC_numberOfSectionsInTableView]; 50 | } 51 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 52 | if ([self.MCDelegate respondsToSelector:@selector(tableView:numberOfRowsInSection:)]) { 53 | return [self.MCDelegate tableView:tableView numberOfRowsInSection:section]; 54 | } 55 | return [self.myManage MC_numberOfRowsInSection:section]; 56 | } 57 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 58 | if ([self.MCDelegate respondsToSelector:@selector(tableView:cellForRowAtIndexPath:)]) { 59 | return [self.MCDelegate tableView:tableView cellForRowAtIndexPath:indexPath]; 60 | } 61 | return (UITableViewCell *)[self.myManage MC_cellForRowAtIndexPath:indexPath withTarget:self.target]; 62 | } 63 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 64 | if ([self.MCDelegate respondsToSelector:@selector(tableView:heightForRowAtIndexPath:)]) { 65 | return [self.MCDelegate tableView:tableView heightForRowAtIndexPath:indexPath]; 66 | } 67 | return [self.myManage MC_cellheightForRowAtIndexPath:indexPath]; 68 | } 69 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 70 | if ([self.MCDelegate respondsToSelector:@selector(tableView:didSelectRowAtIndexPath:)]) { 71 | [self.MCDelegate tableView:tableView didSelectRowAtIndexPath:indexPath]; 72 | return; 73 | } 74 | [self.myManage MC_didSelectRowAtIndexPath:indexPath withTarget:self.target]; 75 | } 76 | - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 77 | if ([self.MCDelegate respondsToSelector:@selector(tableView:heightForFooterInSection:)]) { 78 | return [self.MCDelegate tableView:tableView heightForFooterInSection:section]; 79 | } 80 | return [self.myManage MC_heightForFooterInSection:section]; 81 | } 82 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 83 | if ([self.MCDelegate respondsToSelector:@selector(tableView:heightForHeaderInSection:)]) { 84 | return [self.MCDelegate tableView:tableView heightForHeaderInSection:section]; 85 | } 86 | return [self.myManage MC_heightForHeaderInSection:section]; 87 | } 88 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 89 | if ([self.MCDelegate respondsToSelector:@selector(tableView:viewForHeaderInSection:)]) { 90 | return [self.MCDelegate tableView:tableView viewForHeaderInSection:section]; 91 | } 92 | return [self.myManage MC_viewForHeaderInSection:section]; 93 | } 94 | - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { 95 | if ([self.MCDelegate respondsToSelector:@selector(tableView:viewForFooterInSection:)]) { 96 | return [self.MCDelegate tableView:tableView viewForFooterInSection:section]; 97 | } 98 | return [self.myManage MC_viewForFooterInSection:section]; 99 | } 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2017/10/27. 6 | // Copyright © 2017年 marco chen. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | #import "MCTableViewManager.h" 12 | #import "MCBaseDataModel.h" 13 | #import "MCBaseHeaderFooterDataModel.h" 14 | 15 | #import "AExampleCell.h" 16 | #import "BExampleCell.h" 17 | 18 | #import "CTableViewCell.h" 19 | 20 | #import "InstanceExampleController.h" 21 | #import "FuncInitExampleController.h" 22 | 23 | @interface ViewController () 24 | @property (weak, nonatomic) UITableView *myMCTableView; 25 | @property (nonatomic, copy) NSArray *itemsArray; 26 | @property (strong, nonatomic) MCTableViewManager *myManage; 27 | @end 28 | 29 | @implementation ViewController 30 | 31 | - (void)viewDidLoad { 32 | [super viewDidLoad]; 33 | UITableView * tableView = [[UITableView alloc]initWithFrame:self.view.frame style:UITableViewStyleGrouped]; 34 | tableView.delegate = self; 35 | tableView.dataSource = self; 36 | [self.view addSubview:tableView]; 37 | self.myMCTableView = tableView; 38 | self.myManage = [[MCTableViewManager alloc]init]; 39 | [self loadSettingItems]; 40 | [self.myMCTableView reloadData]; 41 | 42 | } 43 | #pragma mark - 模拟数据加载 44 | - (void)loadSettingItems 45 | { 46 | MCBaseDataModel * IndexCell1 = [[MCBaseDataModel alloc]init]; 47 | IndexCell1.MCItemCell = [CTableViewCell cellWithTableView:self.myMCTableView]; 48 | IndexCell1.MCItemCellParam = @{@"testParam":@"第一种创建cell的方法:直接使用实例"}; 49 | IndexCell1.MCItemHeight = 44; 50 | IndexCell1.MCItemSetDataAction = @"setdata:"; 51 | IndexCell1.MCItemAction = @"pushInstanceController"; 52 | 53 | MCBaseDataModel * IndexCell2 = [[MCBaseDataModel alloc]init]; 54 | IndexCell2.MCItemCell = [CTableViewCell cellWithTableView:self.myMCTableView]; 55 | IndexCell2.MCItemCellParam = @{@"testParam":@"第二种创建cell的方法:调用vc带的创建实例"}; 56 | IndexCell2.MCItemHeight = 44; 57 | IndexCell2.MCItemSetDataAction = @"setdata:"; 58 | IndexCell2.MCItemAction = @"pushFuncInitController"; 59 | 60 | MCBaseHeaderFooterDataModel * section1 = [[MCBaseHeaderFooterDataModel alloc]init]; 61 | section1.items = [NSMutableArray arrayWithArray:@[IndexCell1,IndexCell2]]; 62 | 63 | self.itemsArray = @[ 64 | section1 65 | ]; 66 | [self.myManage updateDatas:[NSMutableArray arrayWithArray:self.itemsArray]]; 67 | 68 | } 69 | #pragma mark - tableview delegate 70 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 71 | return [self.myManage MC_numberOfSectionsInTableView]; 72 | } 73 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 74 | return [self.myManage MC_numberOfRowsInSection:section]; 75 | } 76 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 77 | return (UITableViewCell *)[self.myManage MC_cellForRowAtIndexPath:indexPath withTarget:self]; 78 | } 79 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 80 | return [self.myManage MC_cellheightForRowAtIndexPath:indexPath]; 81 | } 82 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 83 | [self.myManage MC_didSelectRowAtIndexPath:indexPath withTarget:self]; 84 | } 85 | - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 86 | return FLT_MIN; 87 | } 88 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 89 | return FLT_MIN; 90 | } 91 | #pragma mark - 模拟创建cell 92 | - (UITableViewCell *)AExampleCell { 93 | static NSString *ID = @"AExampleCell"; 94 | UITableViewCell *cell = [self.myMCTableView dequeueReusableCellWithIdentifier:ID]; 95 | if (cell == nil) { 96 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; 97 | } 98 | cell.textLabel.text = [NSString stringWithFormat:@"AExampleCell"]; 99 | return cell; 100 | } 101 | 102 | - (UITableViewCell *)BExampleCell:(NSString *)param { 103 | static NSString *ID = @"BExampleCell"; 104 | UITableViewCell *cell = [self.myMCTableView dequeueReusableCellWithIdentifier:ID]; 105 | if (cell == nil) { 106 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; 107 | } 108 | cell.textLabel.text = [NSString stringWithFormat:@"BExampleCell param = %@",param]; 109 | return cell; 110 | } 111 | 112 | - (void)pushInstanceController { 113 | [self.navigationController pushViewController:[[InstanceExampleController alloc]init] animated:YES]; 114 | } 115 | - (void)pushFuncInitController { 116 | [self.navigationController pushViewController:[[FuncInitExampleController alloc]init] animated:YES]; 117 | } 118 | @end 119 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/Controller/InstanceExampleController.m: -------------------------------------------------------------------------------- 1 | // 2 | // InstanceExampleController.m 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2018/8/3. 6 | // Copyright © 2018年 marco chen. All rights reserved. 7 | // 8 | 9 | #import "InstanceExampleController.h" 10 | #import "MCBaseHeaderFooterDataModel.h" 11 | 12 | #import "MCTableViewManager.h" 13 | #import "MCBaseDataModel.h" 14 | #import "AExampleCell.h" 15 | #import "BExampleCell.h" 16 | 17 | #import "CTableViewCell.h" 18 | 19 | @interface InstanceExampleController () 20 | @property (weak, nonatomic) UITableView *myMCTableView; 21 | @property (nonatomic, copy) NSArray *itemsArray; 22 | @property (strong, nonatomic) MCTableViewManager *myManage; 23 | @end 24 | 25 | @implementation InstanceExampleController 26 | 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | UITableView * tableView = [[UITableView alloc]initWithFrame:self.view.frame style:UITableViewStyleGrouped]; 30 | tableView.delegate = self; 31 | tableView.dataSource = self; 32 | [self.view addSubview:tableView]; 33 | self.myMCTableView = tableView; 34 | self.myManage = [[MCTableViewManager alloc]init]; 35 | [self loadSettingItems]; 36 | [self.myMCTableView reloadData]; 37 | 38 | } 39 | #pragma mark - 模拟数据加载 40 | - (void)loadSettingItems 41 | { 42 | MCBaseDataModel * IndexCell1 = [[MCBaseDataModel alloc]init]; 43 | IndexCell1.MCItemCell = [CTableViewCell cellWithTableView:self.myMCTableView]; 44 | IndexCell1.MCItemCellParam = @{@"testParam":@"testParamC1"}; 45 | IndexCell1.MCItemHeight = 44; 46 | IndexCell1.MCItemSetDataAction = @"setdata:"; 47 | IndexCell1.MCItemAction = @"AExampleAction:"; 48 | IndexCell1.MCItemActionParams = @[@"调用vc方法创建"]; 49 | 50 | MCBaseDataModel * IndexCell2 = [[MCBaseDataModel alloc]init]; 51 | IndexCell2.MCItemCell = [CTableViewCell cellWithTableView:self.myMCTableView]; 52 | IndexCell2.MCItemHeight = 44; 53 | IndexCell2.MCItemSetDataAction = @"setdata:"; 54 | IndexCell2.MCItemCellParam = @{@"testParam":@"testParamC2"}; 55 | IndexCell2.MCItemAction = @"BExampleActionMultiplicityParam:withBParam:"; 56 | IndexCell2.MCItemActionParams = @[@"参数一",@"参数二"]; 57 | MCBaseHeaderFooterDataModel * section1 = [[MCBaseHeaderFooterDataModel alloc]init]; 58 | [section1.items addObjectsFromArray:@[IndexCell1]]; 59 | section1.MCItemHeaderHeight = 15; 60 | 61 | MCBaseHeaderFooterDataModel * section2 = [[MCBaseHeaderFooterDataModel alloc]init]; 62 | [section2.items addObjectsFromArray:@[IndexCell2]]; 63 | section2.MCItemHeaderHeight = 5; 64 | 65 | self.itemsArray = @[ 66 | section1, 67 | section2 68 | ]; 69 | [self.myManage updateDatas:[NSMutableArray arrayWithArray:self.itemsArray]]; 70 | 71 | } 72 | #pragma mark - tableview delegate 73 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 74 | return [self.myManage MC_numberOfSectionsInTableView]; 75 | } 76 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 77 | return [self.myManage MC_numberOfRowsInSection:section]; 78 | } 79 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 80 | return (UITableViewCell *)[self.myManage MC_cellForRowAtIndexPath:indexPath withTarget:self]; 81 | } 82 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 83 | return [self.myManage MC_cellheightForRowAtIndexPath:indexPath]; 84 | } 85 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 86 | [self.myManage MC_didSelectRowAtIndexPath:indexPath withTarget:self]; 87 | } 88 | - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 89 | return [self.myManage MC_heightForFooterInSection:section]; 90 | } 91 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 92 | return [self.myManage MC_heightForHeaderInSection:section]; 93 | } 94 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 95 | return [self.myManage MC_viewForHeaderInSection:section]; 96 | } 97 | - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section { 98 | return [self.myManage MC_viewForFooterInSection:section]; 99 | } 100 | 101 | 102 | #pragma mark - 模拟cell的点击事件 103 | - (void)AExampleAction:(NSString *)text { 104 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示"message:text preferredStyle:UIAlertControllerStyleAlert]; 105 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; 106 | UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil]; 107 | 108 | [alertController addAction:cancelAction]; 109 | [alertController addAction:okAction]; 110 | [self presentViewController:alertController animated:YES completion:nil]; 111 | } 112 | 113 | - (void)BExampleActionMultiplicityParam:(NSString *)text withBParam:(NSString *)textB{ 114 | NSLog(@"BExampleAction:%@ textB:%@",text,textB); 115 | int R = (arc4random() % 256); 116 | int G = (arc4random() % 256); 117 | int B = (arc4random() % 256); 118 | self.myMCTableView.backgroundColor = [UIColor colorWithRed:R/255.0 green:G/255.0 blue:B/255.0 alpha:1]; 119 | } 120 | 121 | 122 | @end 123 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample/Controller/FuncInitExampleController.m: -------------------------------------------------------------------------------- 1 | // 2 | // FuncInitExampleController.m 3 | // MCTableViewManagerExample 4 | // 5 | // Created by marco chen on 2018/8/3. 6 | // Copyright © 2018年 marco chen. All rights reserved. 7 | // 8 | 9 | #import "FuncInitExampleController.h" 10 | #import "MCTableViewManager.h" 11 | #import "MCBaseDataModel.h" 12 | #import "MCBaseHeaderFooterDataModel.h" 13 | 14 | #import "AExampleCell.h" 15 | #import "BExampleCell.h" 16 | #import "CTableViewCell.h" 17 | 18 | @interface FuncInitExampleController () 19 | @property (weak, nonatomic) UITableView *myMCTableView; 20 | @property (nonatomic, copy) NSArray *itemsArray; 21 | @property (strong, nonatomic) MCTableViewManager *myManage; 22 | @end 23 | 24 | @implementation FuncInitExampleController 25 | 26 | - (void)viewDidLoad { 27 | [super viewDidLoad]; 28 | UITableView * tableView = [[UITableView alloc]initWithFrame:self.view.frame style:UITableViewStyleGrouped]; 29 | tableView.delegate = self; 30 | tableView.dataSource = self; 31 | [self.view addSubview:tableView]; 32 | self.myMCTableView = tableView; 33 | self.myManage = [[MCTableViewManager alloc]init]; 34 | [self loadSettingItems]; 35 | [self.myMCTableView reloadData]; 36 | 37 | } 38 | #pragma mark - 模拟数据加载 39 | - (void)loadSettingItems { 40 | 41 | MCBaseDataModel * IndexCell1 = [[MCBaseDataModel alloc]init]; 42 | IndexCell1.MCItemCell = @"AExampleCell"; 43 | IndexCell1.MCItemHeight = 44; 44 | IndexCell1.MCItemAction = @"AExampleAction:"; 45 | IndexCell1.MCItemActionParams = @[@"调用vc方法创建"]; 46 | 47 | MCBaseDataModel * IndexCell2 = [[MCBaseDataModel alloc]init]; 48 | IndexCell2.MCItemCell = @"BExampleCell:"; 49 | IndexCell2.MCItemCellParam = @"带参数的创建,调用单参数的方法"; 50 | IndexCell2.MCItemHeight = 44; 51 | IndexCell2.MCItemAction = @"BExampleAction:"; 52 | IndexCell2.MCItemActionParams = @[@"参数一"]; 53 | 54 | MCBaseDataModel * IndexCell3 = [[MCBaseDataModel alloc]init]; 55 | IndexCell3.MCItemCell = @"BExampleCell:"; 56 | IndexCell3.MCItemCellParam = @"带参数的创建,调用多参数的方法"; 57 | IndexCell3.MCItemHeight = 44; 58 | IndexCell3.MCItemAction = @"BExampleActionMultiplicityParam:withBParam:"; 59 | IndexCell3.MCItemActionParams = @[@"参数一",@"参数二"]; 60 | MCBaseHeaderFooterDataModel * section1 = [[MCBaseHeaderFooterDataModel alloc]init]; 61 | [section1.items addObjectsFromArray: @[IndexCell1,IndexCell2,IndexCell3]]; 62 | self.itemsArray = @[ 63 | section1, 64 | ]; 65 | [self.myManage updateDatas:[NSMutableArray arrayWithArray:self.itemsArray]]; 66 | 67 | } 68 | #pragma mark - tableview delegate 69 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 70 | return [self.myManage MC_numberOfSectionsInTableView]; 71 | } 72 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 73 | return [self.myManage MC_numberOfRowsInSection:section]; 74 | } 75 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 76 | return (UITableViewCell *)[self.myManage MC_cellForRowAtIndexPath:indexPath withTarget:self]; 77 | } 78 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 79 | return [self.myManage MC_cellheightForRowAtIndexPath:indexPath]; 80 | } 81 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 82 | [self.myManage MC_didSelectRowAtIndexPath:indexPath withTarget:self]; 83 | } 84 | - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section { 85 | return FLT_MIN; 86 | } 87 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section { 88 | return FLT_MIN; 89 | } 90 | #pragma mark - 模拟创建cell 91 | - (UITableViewCell *)AExampleCell { 92 | static NSString *ID = @"AExampleCell"; 93 | UITableViewCell *cell = [self.myMCTableView dequeueReusableCellWithIdentifier:ID]; 94 | if (cell == nil) { 95 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; 96 | } 97 | cell.textLabel.text = [NSString stringWithFormat:@"不带参数的创建"]; 98 | return cell; 99 | } 100 | 101 | - (UITableViewCell *)BExampleCell:(NSString *)param { 102 | static NSString *ID = @"BExampleCell"; 103 | UITableViewCell *cell = [self.myMCTableView dequeueReusableCellWithIdentifier:ID]; 104 | if (cell == nil) { 105 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; 106 | } 107 | cell.textLabel.text = [NSString stringWithFormat:@"%@",param]; 108 | return cell; 109 | } 110 | #pragma mark - 模拟cell的点击事件 111 | - (void)AExampleAction:(NSString *)text { 112 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示"message:text preferredStyle:UIAlertControllerStyleAlert]; 113 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; 114 | UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil]; 115 | 116 | [alertController addAction:cancelAction]; 117 | [alertController addAction:okAction]; 118 | [self presentViewController:alertController animated:YES completion:nil]; 119 | } 120 | 121 | - (void)BExampleAction:(NSString *)text { 122 | NSLog(@"BExampleAction %@",text); 123 | int R = (arc4random() % 256); 124 | int G = (arc4random() % 256); 125 | int B = (arc4random() % 256); 126 | self.myMCTableView.backgroundColor = [UIColor colorWithRed:R/255.0 green:G/255.0 blue:B/255.0 alpha:1]; 127 | 128 | } 129 | - (void)BExampleActionMultiplicityParam:(NSString *)text withBParam:(NSString *)textB{ 130 | NSLog(@"BExampleAction:%@ textB:%@",text,textB); 131 | int R = (arc4random() % 256); 132 | int G = (arc4random() % 256); 133 | int B = (arc4random() % 256); 134 | self.myMCTableView.backgroundColor = [UIColor colorWithRed:R/255.0 green:G/255.0 blue:B/255.0 alpha:1]; 135 | } 136 | 137 | 138 | @end 139 | -------------------------------------------------------------------------------- /README的副本.md: -------------------------------------------------------------------------------- 1 | # 革命性的UITableView的使用体验,彻底告别 ~~```ifelse```~~ 2 | ![image](https://github.com/CZXBigBrother/MCTableViewManager/blob/master/MC.gif) 3 | ## 曾经的tableview使用 4 | ``` 5 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 6 | { 7 | xxxxCell * cell = [xxxxCell cellWithTableView:tableView]; 8 | if (indexPath.row == 0) { 9 | cell.lblFlageLevel.text = @"xxxxxx"; 10 | }else (indexPath.row == 1) { 11 | cell.lblFlageLevel.text = @"xxxxxx"; 12 | } 13 | return cell; 14 | } 15 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 16 | if (indexPath.row == 2) { 17 | return 10; 18 | } 19 | return 44; 20 | } 21 | ``` 22 | 这种使用方式存在巨大的痛点,每次需要改变tableview的结构都需要改变众多的判断,如果结果复杂,改起来都是崩溃的,包括didSelectRowAtIndexPath方法heightForRowAtIndexPath等等都需要一起改变. 23 | ## Example 24 | #### 为了解决这种问题设计了一套新的使用方式,让tableview之后的使用提供了更好的拓展性,让cell的添加修改拓展完全脱离系统的delegate方法 25 | ###### PS:什么情况下适合使用这套框架:1:tableview中种类多,结果复杂 2:需要更新实际情况动态的改变cell的显示结构,对于这两种情况使用这套框架是非常爽的,但是对于结构单一 比如 只存在一种cell 类型等,就不必使用了,反而会增加你的工作量 26 | ``` 27 | 看看新的使用方式 28 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 29 | return [self.myManage MC_numberOfSectionsInTableView]; 30 | } 31 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 32 | return [self.myManage MC_numberOfRowsInSection:section]; 33 | } 34 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 35 | return (UITableViewCell *)[self.myManage MC_cellForRowAtIndexPath:indexPath withTarget:self]; 36 | } 37 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 38 | return [self.myManage MC_cellheightForRowAtIndexPath:indexPath]; 39 | } 40 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 41 | [self.myManage MC_didSelectRowAtIndexPath:indexPath withTarget:self]; 42 | } 43 | ``` 44 | ### 所有的数据通过一个manager管理,只需要改变manager的数据队列就能改变界面的显示 45 | ``` 46 | 那么我们现在来看看如何来创建cell 和点击的方法 47 | 先创建一个模型,通过字符串转义成SEL的方式创建 48 | @interface MCBaseDataModel : NSObject 49 | 50 | /** 51 | cell的创建方法 52 | */ 53 | @property (copy, nonatomic) NSString *MCItemCell; 54 | 55 | /** 56 | cell的点击selected事件,如果不需要事件,可以赋值为nil或者[nsnull null] 57 | */ 58 | @property (copy, nonatomic) NSString *MCItemAction; 59 | 60 | /** 61 | cell需要赋值的参数 注意:目前只支持一个参数或者nil,如果需要更多参数,可以使用NSDictionary,NSArray,NSSet或者自定义对象等 62 | */ 63 | @property (strong, nonatomic) id MCItemCellParam; 64 | 65 | /** 66 | cell selected事件需要的参数 注意:目前最多支持10个参数 67 | */ 68 | @property (strong, nonatomic) NSArray *MCItemActionParams; 69 | 70 | /** 71 | cell的高度 72 | */ 73 | @property (assign, nonatomic) CGFloat MCItemHeight; 74 | 75 | /** 76 | 一个创建cell的示例 77 | 78 | @param cellParam cell需要的参数 79 | @param acitonParams cell点击事件需要的参数 80 | @return cell对象 81 | */ 82 | + (instancetype)initWithModelWithData:(id)cellParam withAcitonParams:(id)acitonParams; 83 | @end 84 | 85 | + (instancetype)initWithModelWithData:(id)cellParam withAcitonParams:(id)acitonParams 86 | { 87 | AExampleCell * data = [[AExampleCell alloc]init]; 88 | data.MCItemCell = @"AExampleCell"; 89 | data.MCItemAction = @"AExampleAction:"; 90 | data.MCItemHeight = 50; 91 | data.MCItemCellParams = cellParam; 92 | data.MCItemActionParams = acitonParams; 93 | return data; 94 | } 95 | 96 | ViewController 对象模型中的方法 97 | #pragma mark - 模拟创建cell 98 | - (UITableViewCell *)AExampleCell { 99 | static NSString *ID = @"AExampleCell"; 100 | UITableViewCell *cell = [self.myMCTableView dequeueReusableCellWithIdentifier:ID]; 101 | if (cell == nil) { 102 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; 103 | } 104 | cell.textLabel.text = [NSString stringWithFormat:@"AExampleCell"]; 105 | return cell; 106 | } 107 | 108 | - (UITableViewCell *)BExampleCell:(NSString *)param { 109 | static NSString *ID = @"BExampleCell"; 110 | UITableViewCell *cell = [self.myMCTableView dequeueReusableCellWithIdentifier:ID]; 111 | if (cell == nil) { 112 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; 113 | } 114 | cell.textLabel.text = [NSString stringWithFormat:@"BExampleCell param = %@",param]; 115 | return cell; 116 | } 117 | #pragma mark - 模拟cell的点击事件 118 | - (void)AExampleAction:(NSString *)text { 119 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示"message:text preferredStyle:UIAlertControllerStyleAlert]; 120 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; 121 | UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil]; 122 | 123 | [alertController addAction:cancelAction]; 124 | [alertController addAction:okAction]; 125 | [self presentViewController:alertController animated:YES completion:nil]; 126 | } 127 | 128 | - (void)BExampleAction:(NSString *)text { 129 | NSLog(@"BExampleAction %@",text); 130 | int R = (arc4random() % 256); 131 | int G = (arc4random() % 256); 132 | int B = (arc4random() % 256); 133 | self.myMCTableView.backgroundColor = [UIColor colorWithRed:R/255.0 green:G/255.0 blue:B/255.0 alpha:1]; 134 | 135 | } 136 | 137 | ``` 138 | ## Usage 139 | ### 加载数据的方式 140 | ``` 141 | #pragma mark - 模拟数据加载 142 | - (void)loadSettingItems 143 | { 144 | self.itemsArray = @[ 145 | @[[AExampleCell initWithModelWithData:nil withAcitonParams:@[@"AcitonParam --- A"]]], 146 | @[[BExampleCell initWithModelWithData:@"B Name" withAcitonParams:@[@"AcitonParam --- B"]]] 147 | ]; 148 | [self.myManage updateDatas:[NSMutableArray arrayWithArray:self.itemsArray]]; 149 | } 150 | ``` 151 | 在以后的使用时,需要添加一个cell 类型只需要添加一个类似```- (UITableViewCell *)BExampleCell```的方法,然后改变myManage队列中的数据,就可以重新显示,使之后的使用中完全脱离tableview delegate 152 | ## Extensions 153 | ``` 154 | /** 155 | 初始化 156 | 157 | @param data 数据队列 158 | */ 159 | - (instancetype)initWithDatas:(NSMutableArray *)data; 160 | 161 | /** 162 | 更新队列 163 | 164 | @param data 队列数据 165 | */ 166 | - (void)updateDatas:(NSMutableArray *)data; 167 | /** 168 | 返回cell 169 | 170 | @param indexPath 和系统返回的indexPath相同 171 | @param target 执行方法的对象 172 | @return 对象 173 | */ 174 | - (instancetype)MC_cellForRowAtIndexPath:(NSIndexPath *)indexPath withTarget:(id)target; 175 | 176 | /** 177 | 返回cell高度 178 | 179 | @param indexPath 和系统返回的indexPath相同 180 | @return 高度 181 | */ 182 | - (CGFloat)MC_cellheightForRowAtIndexPath:(NSIndexPath *)indexPath; 183 | 184 | /** 185 | 返回cell点击事件 186 | 187 | @param indexPath 和系统返回的indexPath相同 188 | @param target 执行方法的对象 189 | */ 190 | - (void)MC_didSelectRowAtIndexPath:(NSIndexPath *)indexPath withTarget:(id)target; 191 | 192 | /** 193 | 返回队列组数 194 | 195 | @return 返回队列组数 196 | */ 197 | - (NSInteger)MC_numberOfSectionsInTableView; 198 | 199 | /** 200 | 返回队列组中的个数 201 | 202 | @param section 组index 203 | @return 返回队列组中的个数 204 | */ 205 | - (NSInteger)MC_numberOfRowsInSection:(NSInteger)section; 206 | ``` 207 | ## 实现原理 208 | 主要通过objectiv-c动态的属性,直接将string转成SEL然后去执行,原理非常的简单,中间也借鉴了jspatch部分的写法,本质上就是下面这样一句话 209 | ``` 210 | id (*new_msgSend0)(id, SEL,...) = (id (*)(id, SEL,...)) objc_msgSend; 211 | ``` 212 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 革命性的UITableView的使用体验,彻底告别(新版本正在测试中,文档还未更新) ~~```ifelse```~~ 2 | ![image](https://github.com/CZXBigBrother/MCTableViewManager/blob/master/MC.gif) 3 | ## 曾经的tableview使用(新版本正在测试中,文档还未更新 4 | ``` 5 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 6 | { 7 | xxxxCell * cell = [xxxxCell cellWithTableView:tableView]; 8 | if (indexPath.row == 0) { 9 | cell.lblFlageLevel.text = @"xxxxxx"; 10 | }else (indexPath.row == 1) { 11 | cell.lblFlageLevel.text = @"xxxxxx"; 12 | } 13 | return cell; 14 | } 15 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 16 | if (indexPath.row == 2) { 17 | return 10; 18 | } 19 | return 44; 20 | } 21 | ``` 22 | 这种使用方式存在巨大的痛点,每次需要改变tableview的结构都需要改变众多的判断,如果结果复杂,改起来都是崩溃的,包括didSelectRowAtIndexPath方法heightForRowAtIndexPath等等都需要一起改变. 23 | ## Example 24 | #### 为了解决这种问题设计了一套新的使用方式,让tableview之后的使用提供了更好的拓展性,让cell的添加修改拓展完全脱离系统的delegate方法 25 | ###### PS:什么情况下适合使用这套框架:1:tableview中种类多,结果复杂 2:需要更新实际情况动态的改变cell的显示结构,对于这两种情况使用这套框架是非常爽的,但是对于结构单一 比如 只存在一种cell 类型等,就不必使用了,反而会增加你的工作量 26 | ``` 27 | 看看新的使用方式 28 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 29 | return [self.myManage MC_numberOfSectionsInTableView]; 30 | } 31 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 32 | return [self.myManage MC_numberOfRowsInSection:section]; 33 | } 34 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 35 | return (UITableViewCell *)[self.myManage MC_cellForRowAtIndexPath:indexPath withTarget:self]; 36 | } 37 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 38 | return [self.myManage MC_cellheightForRowAtIndexPath:indexPath]; 39 | } 40 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 41 | [self.myManage MC_didSelectRowAtIndexPath:indexPath withTarget:self]; 42 | } 43 | ``` 44 | ### 所有的数据通过一个manager管理,只需要改变manager的数据队列就能改变界面的显示 45 | ``` 46 | 那么我们现在来看看如何来创建cell 和点击的方法 47 | 先创建一个模型,通过字符串转义成SEL的方式创建 48 | @interface MCBaseDataModel : NSObject 49 | 50 | /** 51 | cell的创建方法 52 | */ 53 | @property (copy, nonatomic) NSString *MCItemCell; 54 | 55 | /** 56 | cell的点击selected事件,如果不需要事件,可以赋值为nil或者[nsnull null] 57 | */ 58 | @property (copy, nonatomic) NSString *MCItemAction; 59 | 60 | /** 61 | cell需要赋值的参数 注意:目前只支持一个参数或者nil,如果需要更多参数,可以使用NSDictionary,NSArray,NSSet或者自定义对象等 62 | */ 63 | @property (strong, nonatomic) id MCItemCellParam; 64 | 65 | /** 66 | cell selected事件需要的参数 注意:目前最多支持10个参数 67 | */ 68 | @property (strong, nonatomic) NSArray *MCItemActionParams; 69 | 70 | /** 71 | cell的高度 72 | */ 73 | @property (assign, nonatomic) CGFloat MCItemHeight; 74 | 75 | /** 76 | 一个创建cell的示例 77 | 78 | @param cellParam cell需要的参数 79 | @param acitonParams cell点击事件需要的参数 80 | @return cell对象 81 | */ 82 | + (instancetype)initWithModelWithData:(id)cellParam withAcitonParams:(id)acitonParams; 83 | @end 84 | 85 | + (instancetype)initWithModelWithData:(id)cellParam withAcitonParams:(id)acitonParams 86 | { 87 | AExampleCell * data = [[AExampleCell alloc]init]; 88 | data.MCItemCell = @"AExampleCell"; 89 | data.MCItemAction = @"AExampleAction:"; 90 | data.MCItemHeight = 50; 91 | data.MCItemCellParams = cellParam; 92 | data.MCItemActionParams = acitonParams; 93 | return data; 94 | } 95 | 96 | ViewController 对象模型中的方法 97 | #pragma mark - 模拟创建cell 98 | - (UITableViewCell *)AExampleCell { 99 | static NSString *ID = @"AExampleCell"; 100 | UITableViewCell *cell = [self.myMCTableView dequeueReusableCellWithIdentifier:ID]; 101 | if (cell == nil) { 102 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; 103 | } 104 | cell.textLabel.text = [NSString stringWithFormat:@"AExampleCell"]; 105 | return cell; 106 | } 107 | 108 | - (UITableViewCell *)BExampleCell:(NSString *)param { 109 | static NSString *ID = @"BExampleCell"; 110 | UITableViewCell *cell = [self.myMCTableView dequeueReusableCellWithIdentifier:ID]; 111 | if (cell == nil) { 112 | cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; 113 | } 114 | cell.textLabel.text = [NSString stringWithFormat:@"BExampleCell param = %@",param]; 115 | return cell; 116 | } 117 | #pragma mark - 模拟cell的点击事件 118 | - (void)AExampleAction:(NSString *)text { 119 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"提示"message:text preferredStyle:UIAlertControllerStyleAlert]; 120 | UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil]; 121 | UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"好的" style:UIAlertActionStyleDefault handler:nil]; 122 | 123 | [alertController addAction:cancelAction]; 124 | [alertController addAction:okAction]; 125 | [self presentViewController:alertController animated:YES completion:nil]; 126 | } 127 | 128 | - (void)BExampleAction:(NSString *)text { 129 | NSLog(@"BExampleAction %@",text); 130 | int R = (arc4random() % 256); 131 | int G = (arc4random() % 256); 132 | int B = (arc4random() % 256); 133 | self.myMCTableView.backgroundColor = [UIColor colorWithRed:R/255.0 green:G/255.0 blue:B/255.0 alpha:1]; 134 | 135 | } 136 | 137 | ``` 138 | ## Usage 139 | ### 加载数据的方式 140 | ``` 141 | #pragma mark - 模拟数据加载 142 | - (void)loadSettingItems 143 | { 144 | self.itemsArray = @[ 145 | @[[AExampleCell initWithModelWithData:nil withAcitonParams:@[@"AcitonParam --- A"]]], 146 | @[[BExampleCell initWithModelWithData:@"B Name" withAcitonParams:@[@"AcitonParam --- B"]]] 147 | ]; 148 | [self.myManage updateDatas:[NSMutableArray arrayWithArray:self.itemsArray]]; 149 | } 150 | ``` 151 | 在以后的使用时,需要添加一个cell 类型只需要添加一个类似```- (UITableViewCell *)BExampleCell```的方法,然后改变myManage队列中的数据,就可以重新显示,使之后的使用中完全脱离tableview delegate 152 | ## Extensions 153 | ``` 154 | /** 155 | 初始化 156 | 157 | @param data 数据队列 158 | */ 159 | - (instancetype)initWithDatas:(NSMutableArray *)data; 160 | 161 | /** 162 | 更新队列 163 | 164 | @param data 队列数据 165 | */ 166 | - (void)updateDatas:(NSMutableArray *)data; 167 | /** 168 | 返回cell 169 | 170 | @param indexPath 和系统返回的indexPath相同 171 | @param target 执行方法的对象 172 | @return 对象 173 | */ 174 | - (instancetype)MC_cellForRowAtIndexPath:(NSIndexPath *)indexPath withTarget:(id)target; 175 | 176 | /** 177 | 返回cell高度 178 | 179 | @param indexPath 和系统返回的indexPath相同 180 | @return 高度 181 | */ 182 | - (CGFloat)MC_cellheightForRowAtIndexPath:(NSIndexPath *)indexPath; 183 | 184 | /** 185 | 返回cell点击事件 186 | 187 | @param indexPath 和系统返回的indexPath相同 188 | @param target 执行方法的对象 189 | */ 190 | - (void)MC_didSelectRowAtIndexPath:(NSIndexPath *)indexPath withTarget:(id)target; 191 | 192 | /** 193 | 返回队列组数 194 | 195 | @return 返回队列组数 196 | */ 197 | - (NSInteger)MC_numberOfSectionsInTableView; 198 | 199 | /** 200 | 返回队列组中的个数 201 | 202 | @param section 组index 203 | @return 返回队列组中的个数 204 | */ 205 | - (NSInteger)MC_numberOfRowsInSection:(NSInteger)section; 206 | ``` 207 | ## 实现原理 208 | 主要通过objectiv-c动态的属性,直接将string转成SEL然后去执行,原理非常的简单,中间也借鉴了jspatch部分的写法,本质上就是下面这样一句话 209 | ``` 210 | id (*new_msgSend0)(id, SEL,...) = (id (*)(id, SEL,...)) objc_msgSend; 211 | ``` 212 | -------------------------------------------------------------------------------- /MCTableViewManager/MCTableViewManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // MCTableViewManager.m 3 | // MCTableView 4 | // 5 | // Created by marco chen on 2017/10/25. 6 | // Copyright © 2017年 marco chen. All rights reserved. 7 | // 8 | 9 | 10 | #import "MCTableViewManager.h" 11 | #import "MCBaseDataModel.h" 12 | #import "MCBaseHeaderFooterDataModel.h" 13 | #import 14 | #import 15 | 16 | static NSString * const kShireItemAction = @"MCItemAction"; 17 | static NSString * const kShireItemCell = @"MCItemCell"; 18 | static NSString * const kShireItemHeight = @"MCItemHeight"; 19 | static NSString * const kShireCellItemParam = @"MCItemCellParam"; 20 | static NSString * const kShireActionItemParam = @"MCItemActionParams"; 21 | static NSString * const kShireSetDataActionItemParam = @"MCItemSetDataAction"; 22 | 23 | 24 | @interface MCTableViewManager() 25 | @property (strong, nonatomic) NSMutableArray *GlobalData; 26 | @end 27 | 28 | @implementation MCTableViewManager 29 | #pragma mark - init 30 | - (instancetype)initWithDatas:(NSMutableArray *)data { 31 | if (self == [super init]) { 32 | self.GlobalData = data; 33 | } 34 | return self; 35 | } 36 | - (void)updateDatas:(NSMutableArray *)data { 37 | self.GlobalData = data; 38 | } 39 | 40 | #pragma mark - cell 41 | - (id)MC_cellForRowAtIndexPath:(NSIndexPath *)indexPath withTarget:(id)target{ 42 | MCBaseDataModel *item = [self.GlobalData[indexPath.section] items][indexPath.row]; 43 | id cell = [item valueForKeyPath:kShireItemCell]; 44 | if ([cell isKindOfClass:[NSString class]]) { 45 | SEL getCellSelector = NSSelectorFromString(cell); 46 | return [self funcTarget:target withArgument:[item valueForKeyPath:kShireCellItemParam] withSelector:getCellSelector]; 47 | }else if([cell isKindOfClass:[UITableViewCell class]]){ 48 | SEL getCellSelector = NSSelectorFromString([item valueForKeyPath:kShireSetDataActionItemParam]); 49 | [self funcTarget:cell withArgument:[item valueForKeyPath:kShireCellItemParam] withSelector:getCellSelector]; 50 | return cell; 51 | }else { 52 | return (id)[[UITableViewCell alloc]init]; 53 | } 54 | 55 | } 56 | - (CGFloat)MC_cellheightForRowAtIndexPath:(NSIndexPath *)indexPath { 57 | MCBaseDataModel *item = [self.GlobalData[indexPath.section] items][indexPath.row]; 58 | return [[item valueForKeyPath:kShireItemHeight] doubleValue]; 59 | } 60 | - (void)MC_didSelectRowAtIndexPath:(NSIndexPath *)indexPath withTarget:(id)target { 61 | MCBaseDataModel *item = [self.GlobalData[indexPath.section] items][indexPath.row]; 62 | if ([[item valueForKeyPath:kShireItemAction] isEqual:[NSNull null]] || [item valueForKeyPath:kShireItemAction] == nil) {return;} 63 | SEL actionSelector = NSSelectorFromString([item valueForKeyPath:kShireItemAction]); 64 | if ([target respondsToSelector:actionSelector]) { 65 | [self productFuncTarget:target withArgumentsList:[item valueForKeyPath:kShireActionItemParam] withSelector:actionSelector]; 66 | }else { 67 | NSAssert([target respondsToSelector:actionSelector], @"unrecognized selector crash %@",[item valueForKeyPath:kShireItemAction]); 68 | } 69 | } 70 | - (NSInteger)MC_numberOfSectionsInTableView { 71 | return [self.GlobalData count]; 72 | } 73 | - (NSInteger)MC_numberOfRowsInSection:(NSInteger)section { 74 | return [[self.GlobalData[section]items] count]; 75 | } 76 | - (CGFloat)MC_heightForFooterInSection:(NSInteger)section { 77 | return [self.GlobalData[section]MCItemFooterHeight] ? :FLT_MIN; 78 | } 79 | - (CGFloat)MC_heightForHeaderInSection:(NSInteger)section { 80 | return [self.GlobalData[section]MCItemHeaderHeight] ? :FLT_MIN; 81 | } 82 | - (UIView *)MC_viewForHeaderInSection:(NSInteger)section { 83 | return [self.GlobalData[section]MCItemHeader]; 84 | } 85 | - (UIView *)MC_viewForFooterInSection:(NSInteger)section { 86 | return [self.GlobalData[section]MCItemFooter]; 87 | } 88 | #pragma mark - lazy 89 | - (NSMutableArray *)GlobalData { 90 | if(_GlobalData == nil) { 91 | _GlobalData = [NSMutableArray array]; 92 | } 93 | return _GlobalData; 94 | } 95 | #pragma mark - runtime 96 | /** 97 | 创建一个存在返回的函数 98 | 99 | @param sender 实现函数的对象 100 | @param param 传入的参数 101 | @param selector SEL 102 | @return 执行之后返回的对象 103 | */ 104 | - (id)funcTarget:(id)sender withArgument:(id)param withSelector:(SEL)selector { 105 | id (*new_msgSend0)(id, SEL,...) = (id (*)(id, SEL,...)) objc_msgSend; 106 | id (*new_msgSend1)(id, SEL, id,...) = (id (*)(id, SEL, id,...)) objc_msgSend; 107 | return (param == nil || param == [NSNull null]) ? new_msgSend0(sender,selector) : new_msgSend1(sender,selector,param); 108 | } 109 | 110 | /** 111 | 创建一个不存在返回值的函数 112 | 113 | @param sender 实现函数的对象 114 | @param params 传入的参数(必须是数组) 115 | @param selector SEL 116 | */ 117 | - (void)productFuncTarget:(id)sender withArgumentsList:(id)params withSelector:(SEL)selector { 118 | NSMutableArray *argumentsList = [[NSMutableArray alloc] initWithArray:params]; 119 | NSUInteger numberOfArguments = [argumentsList count]; 120 | //PS:这段我就是抄JP的 121 | //https://gist.github.com/bang590/ca3720ae1da594252a2e 122 | void (*new_msgSend0)(id, SEL,...) = (void (*)(id, SEL,...)) objc_msgSend; 123 | void (*new_msgSend1)(id, SEL, id,...) = (void (*)(id, SEL, id,...)) objc_msgSend; 124 | void (*new_msgSend2)(id, SEL, id, id,...) = (void (*)(id, SEL, id, id,...)) objc_msgSend; 125 | void (*new_msgSend3)(id, SEL, id, id, id,...) = (void (*)(id, SEL, id, id, id,...)) objc_msgSend; 126 | void (*new_msgSend4)(id, SEL, id, id, id, id,...) = (void (*)(id, SEL, id, id, id, id,...)) objc_msgSend; 127 | void (*new_msgSend5)(id, SEL, id, id, id, id, id,...) = (void (*)(id, SEL, id, id, id, id, id,...)) objc_msgSend; 128 | void (*new_msgSend6)(id, SEL, id, id, id, id, id, id,...) = (void (*)(id, SEL, id, id, id, id, id, id,...)) objc_msgSend; 129 | void (*new_msgSend7)(id, SEL, id, id, id, id, id, id, id,...) = (void (*)(id, SEL, id, id, id, id, id, id,id,...)) objc_msgSend; 130 | void (*new_msgSend8)(id, SEL, id, id, id, id, id, id, id, id,...) = (void (*)(id, SEL, id, id, id, id, id, id, id, id,...)) objc_msgSend; 131 | void (*new_msgSend9)(id, SEL, id, id, id, id, id, id, id, id, id,...) = (void (*)(id, SEL, id, id, id, id, id, id, id, id, id, ...)) objc_msgSend; 132 | void (*new_msgSend10)(id, SEL, id, id, id, id, id, id, id, id, id, id,...) = (void (*)(id, SEL, id, id, id, id, id, id, id, id, id, id,...)) objc_msgSend; 133 | #define JP_G_ARG(idx) (argumentsList[idx]) 134 | #define JP_CALL_MSGSEND_ARG0(_num) new_msgSend##_num(sender, selector); 135 | #define JP_CALL_MSGSEND_ARG1(_num) new_msgSend##_num(sender, selector, JP_G_ARG(0)); 136 | #define JP_CALL_MSGSEND_ARG2(_num) new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1)); 137 | #define JP_CALL_MSGSEND_ARG3(_num) new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2)); 138 | #define JP_CALL_MSGSEND_ARG4(_num) new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3)); 139 | #define JP_CALL_MSGSEND_ARG5(_num) new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3), JP_G_ARG(4)); 140 | #define JP_CALL_MSGSEND_ARG6(_num) new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3), JP_G_ARG(4), JP_G_ARG(5)); 141 | #define JP_CALL_MSGSEND_ARG7(_num) new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3), JP_G_ARG(4), JP_G_ARG(5), JP_G_ARG(6)); 142 | #define JP_CALL_MSGSEND_ARG8(_num) new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3), JP_G_ARG(4), JP_G_ARG(5), JP_G_ARG(6), JP_G_ARG(7)); 143 | #define JP_CALL_MSGSEND_ARG9(_num) new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3), JP_G_ARG(4), JP_G_ARG(5), JP_G_ARG(6), JP_G_ARG(7), JP_G_ARG(8)); 144 | #define JP_CALL_MSGSEND_ARG10(_num) new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3), JP_G_ARG(4), JP_G_ARG(5), JP_G_ARG(6), JP_G_ARG(7), JP_G_ARG(8), JP_G_ARG(9)); 145 | #define JP_CALL_MSGSEND_ARG11(_num) new_msgSend##_num(sender, selector, JP_G_ARG(0), JP_G_ARG(1), JP_G_ARG(2), JP_G_ARG(3), JP_G_ARG(4), JP_G_ARG(5), JP_G_ARG(6), JP_G_ARG(7), JP_G_ARG(8), JP_G_ARG(9), JP_G_ARG(10)); 146 | 147 | #define JP_IF_REAL_ARG_COUNT(_num) if([argumentsList count] == _num) 148 | #define JP_DEAL_MSGSEND(_realArgCount, _defineArgCount) \ 149 | if(numberOfArguments == _defineArgCount) { \ 150 | JP_CALL_MSGSEND_ARG##_realArgCount(_defineArgCount) \ 151 | } 152 | JP_IF_REAL_ARG_COUNT(0) { JP_CALL_MSGSEND_ARG0(0) } 153 | JP_IF_REAL_ARG_COUNT(1) { JP_CALL_MSGSEND_ARG1(1) } 154 | JP_IF_REAL_ARG_COUNT(2) { JP_DEAL_MSGSEND(2, 1) JP_DEAL_MSGSEND(2, 2) } 155 | JP_IF_REAL_ARG_COUNT(3) { JP_DEAL_MSGSEND(3, 1) JP_DEAL_MSGSEND(3, 2) JP_DEAL_MSGSEND(3, 3) } 156 | JP_IF_REAL_ARG_COUNT(4) { JP_DEAL_MSGSEND(4, 1) JP_DEAL_MSGSEND(4, 2) JP_DEAL_MSGSEND(4, 3) JP_DEAL_MSGSEND(4, 4) } 157 | JP_IF_REAL_ARG_COUNT(5) { JP_DEAL_MSGSEND(5, 1) JP_DEAL_MSGSEND(5, 2) JP_DEAL_MSGSEND(5, 3) JP_DEAL_MSGSEND(5, 4) JP_DEAL_MSGSEND(5, 5) } 158 | JP_IF_REAL_ARG_COUNT(6) { JP_DEAL_MSGSEND(6, 1) JP_DEAL_MSGSEND(6, 2) JP_DEAL_MSGSEND(6, 3) JP_DEAL_MSGSEND(6, 4) JP_DEAL_MSGSEND(6, 5) JP_DEAL_MSGSEND(6, 6) } 159 | JP_IF_REAL_ARG_COUNT(7) { JP_DEAL_MSGSEND(7, 1) JP_DEAL_MSGSEND(7, 2) JP_DEAL_MSGSEND(7, 3) JP_DEAL_MSGSEND(7, 4) JP_DEAL_MSGSEND(7, 5) JP_DEAL_MSGSEND(7, 6) JP_DEAL_MSGSEND(7, 7) } 160 | JP_IF_REAL_ARG_COUNT(8) { JP_DEAL_MSGSEND(8, 1) JP_DEAL_MSGSEND(8, 2) JP_DEAL_MSGSEND(8, 3) JP_DEAL_MSGSEND(8, 4) JP_DEAL_MSGSEND(8, 5) JP_DEAL_MSGSEND(8, 6) JP_DEAL_MSGSEND(8, 7) JP_DEAL_MSGSEND(8, 8) } 161 | JP_IF_REAL_ARG_COUNT(9) { JP_DEAL_MSGSEND(9, 1) JP_DEAL_MSGSEND(9, 2) JP_DEAL_MSGSEND(9, 3) JP_DEAL_MSGSEND(9, 4) JP_DEAL_MSGSEND(9, 5) JP_DEAL_MSGSEND(9, 6) JP_DEAL_MSGSEND(9, 7) JP_DEAL_MSGSEND(9, 8) JP_DEAL_MSGSEND(9, 9) } 162 | JP_IF_REAL_ARG_COUNT(10) { JP_DEAL_MSGSEND(10, 1) JP_DEAL_MSGSEND(10, 2) JP_DEAL_MSGSEND(10, 3) JP_DEAL_MSGSEND(10, 4) JP_DEAL_MSGSEND(10, 5) JP_DEAL_MSGSEND(10, 6) JP_DEAL_MSGSEND(10, 7) JP_DEAL_MSGSEND(10, 8) JP_DEAL_MSGSEND(10, 9) JP_DEAL_MSGSEND(10, 10) } 163 | } 164 | 165 | @end 166 | -------------------------------------------------------------------------------- /MCTableViewManagerExample/MCTableViewManagerExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 48; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 4118E7572112F60B007C577A /* MCTableViewManagerExampleTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 4118E7562112F60B007C577A /* MCTableViewManagerExampleTests.m */; }; 11 | 41AEDA93211AD73900208023 /* MCBaseHeaderFooterDataModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 41AEDA92211AD73900208023 /* MCBaseHeaderFooterDataModel.m */; }; 12 | 41CE55E7211303570081F3A9 /* CTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 41CE55E6211303570081F3A9 /* CTableViewCell.m */; }; 13 | 41CE55EA21141F060081F3A9 /* InstanceExampleController.m in Sources */ = {isa = PBXBuildFile; fileRef = 41CE55E921141F060081F3A9 /* InstanceExampleController.m */; }; 14 | 41CE55ED211422C80081F3A9 /* FuncInitExampleController.m in Sources */ = {isa = PBXBuildFile; fileRef = 41CE55EC211422C80081F3A9 /* FuncInitExampleController.m */; }; 15 | 41CE55F021143AAA0081F3A9 /* MCTableViewDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 41CE55EF21143AAA0081F3A9 /* MCTableViewDelegate.m */; }; 16 | 41E2BAD91FA31B9D0086BA89 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 41E2BAD81FA31B9D0086BA89 /* AppDelegate.m */; }; 17 | 41E2BADC1FA31B9D0086BA89 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 41E2BADB1FA31B9D0086BA89 /* ViewController.m */; }; 18 | 41E2BAE11FA31B9D0086BA89 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 41E2BAE01FA31B9D0086BA89 /* Assets.xcassets */; }; 19 | 41E2BAE41FA31B9D0086BA89 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 41E2BAE21FA31B9D0086BA89 /* LaunchScreen.storyboard */; }; 20 | 41E2BAE71FA31B9D0086BA89 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 41E2BAE61FA31B9D0086BA89 /* main.m */; }; 21 | 41E2BAF21FA31CFC0086BA89 /* MCBaseDataModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 41E2BAEF1FA31C080086BA89 /* MCBaseDataModel.m */; }; 22 | 41E2BAF31FA31CFD0086BA89 /* MCTableViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 41E2BAF11FA31C080086BA89 /* MCTableViewManager.m */; }; 23 | 41E2BAF61FA31DDF0086BA89 /* AExampleCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 41E2BAF51FA31DDF0086BA89 /* AExampleCell.m */; }; 24 | 41E2BAF91FA31DF20086BA89 /* BExampleCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 41E2BAF81FA31DF20086BA89 /* BExampleCell.m */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXContainerItemProxy section */ 28 | 4118E7592112F60B007C577A /* PBXContainerItemProxy */ = { 29 | isa = PBXContainerItemProxy; 30 | containerPortal = 41E2BACC1FA31B9C0086BA89 /* Project object */; 31 | proxyType = 1; 32 | remoteGlobalIDString = 41E2BAD31FA31B9C0086BA89; 33 | remoteInfo = MCTableViewManagerExample; 34 | }; 35 | /* End PBXContainerItemProxy section */ 36 | 37 | /* Begin PBXFileReference section */ 38 | 4118E7542112F60B007C577A /* MCTableViewManagerExampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MCTableViewManagerExampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 39 | 4118E7562112F60B007C577A /* MCTableViewManagerExampleTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MCTableViewManagerExampleTests.m; sourceTree = ""; }; 40 | 4118E7582112F60B007C577A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 41 | 41AEDA91211AD73900208023 /* MCBaseHeaderFooterDataModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCBaseHeaderFooterDataModel.h; sourceTree = ""; }; 42 | 41AEDA92211AD73900208023 /* MCBaseHeaderFooterDataModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MCBaseHeaderFooterDataModel.m; sourceTree = ""; }; 43 | 41CE55E5211303570081F3A9 /* CTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CTableViewCell.h; sourceTree = ""; }; 44 | 41CE55E6211303570081F3A9 /* CTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CTableViewCell.m; sourceTree = ""; }; 45 | 41CE55E821141F060081F3A9 /* InstanceExampleController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = InstanceExampleController.h; sourceTree = ""; }; 46 | 41CE55E921141F060081F3A9 /* InstanceExampleController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = InstanceExampleController.m; sourceTree = ""; }; 47 | 41CE55EB211422C80081F3A9 /* FuncInitExampleController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FuncInitExampleController.h; sourceTree = ""; }; 48 | 41CE55EC211422C80081F3A9 /* FuncInitExampleController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FuncInitExampleController.m; sourceTree = ""; }; 49 | 41CE55EE21143AAA0081F3A9 /* MCTableViewDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCTableViewDelegate.h; sourceTree = ""; }; 50 | 41CE55EF21143AAA0081F3A9 /* MCTableViewDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MCTableViewDelegate.m; sourceTree = ""; }; 51 | 41E2BAD41FA31B9C0086BA89 /* MCTableViewManagerExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MCTableViewManagerExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | 41E2BAD71FA31B9C0086BA89 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 53 | 41E2BAD81FA31B9D0086BA89 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 54 | 41E2BADA1FA31B9D0086BA89 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 55 | 41E2BADB1FA31B9D0086BA89 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 56 | 41E2BAE01FA31B9D0086BA89 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 57 | 41E2BAE31FA31B9D0086BA89 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 58 | 41E2BAE51FA31B9D0086BA89 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 59 | 41E2BAE61FA31B9D0086BA89 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 60 | 41E2BAEE1FA31C080086BA89 /* MCBaseDataModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCBaseDataModel.h; sourceTree = ""; }; 61 | 41E2BAEF1FA31C080086BA89 /* MCBaseDataModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MCBaseDataModel.m; sourceTree = ""; }; 62 | 41E2BAF01FA31C080086BA89 /* MCTableViewManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MCTableViewManager.h; sourceTree = ""; }; 63 | 41E2BAF11FA31C080086BA89 /* MCTableViewManager.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MCTableViewManager.m; sourceTree = ""; }; 64 | 41E2BAF41FA31DDF0086BA89 /* AExampleCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AExampleCell.h; sourceTree = ""; }; 65 | 41E2BAF51FA31DDF0086BA89 /* AExampleCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AExampleCell.m; sourceTree = ""; }; 66 | 41E2BAF71FA31DF20086BA89 /* BExampleCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BExampleCell.h; sourceTree = ""; }; 67 | 41E2BAF81FA31DF20086BA89 /* BExampleCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BExampleCell.m; sourceTree = ""; }; 68 | /* End PBXFileReference section */ 69 | 70 | /* Begin PBXFrameworksBuildPhase section */ 71 | 4118E7512112F60A007C577A /* Frameworks */ = { 72 | isa = PBXFrameworksBuildPhase; 73 | buildActionMask = 2147483647; 74 | files = ( 75 | ); 76 | runOnlyForDeploymentPostprocessing = 0; 77 | }; 78 | 41E2BAD11FA31B9C0086BA89 /* Frameworks */ = { 79 | isa = PBXFrameworksBuildPhase; 80 | buildActionMask = 2147483647; 81 | files = ( 82 | ); 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | /* End PBXFrameworksBuildPhase section */ 86 | 87 | /* Begin PBXGroup section */ 88 | 4118E7552112F60B007C577A /* MCTableViewManagerExampleTests */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 4118E7562112F60B007C577A /* MCTableViewManagerExampleTests.m */, 92 | 4118E7582112F60B007C577A /* Info.plist */, 93 | ); 94 | path = MCTableViewManagerExampleTests; 95 | sourceTree = ""; 96 | }; 97 | 41CE55F121143AFF0081F3A9 /* View */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 41CE55E5211303570081F3A9 /* CTableViewCell.h */, 101 | 41CE55E6211303570081F3A9 /* CTableViewCell.m */, 102 | 41E2BAF41FA31DDF0086BA89 /* AExampleCell.h */, 103 | 41E2BAF51FA31DDF0086BA89 /* AExampleCell.m */, 104 | 41E2BAF71FA31DF20086BA89 /* BExampleCell.h */, 105 | 41E2BAF81FA31DF20086BA89 /* BExampleCell.m */, 106 | ); 107 | path = View; 108 | sourceTree = ""; 109 | }; 110 | 41CE55F221143B0A0081F3A9 /* Controller */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | 41CE55EB211422C80081F3A9 /* FuncInitExampleController.h */, 114 | 41CE55EC211422C80081F3A9 /* FuncInitExampleController.m */, 115 | 41CE55E821141F060081F3A9 /* InstanceExampleController.h */, 116 | 41CE55E921141F060081F3A9 /* InstanceExampleController.m */, 117 | ); 118 | path = Controller; 119 | sourceTree = ""; 120 | }; 121 | 41E2BACB1FA31B9C0086BA89 = { 122 | isa = PBXGroup; 123 | children = ( 124 | 41E2BAD61FA31B9C0086BA89 /* MCTableViewManagerExample */, 125 | 4118E7552112F60B007C577A /* MCTableViewManagerExampleTests */, 126 | 41E2BAD51FA31B9C0086BA89 /* Products */, 127 | ); 128 | sourceTree = ""; 129 | }; 130 | 41E2BAD51FA31B9C0086BA89 /* Products */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 41E2BAD41FA31B9C0086BA89 /* MCTableViewManagerExample.app */, 134 | 4118E7542112F60B007C577A /* MCTableViewManagerExampleTests.xctest */, 135 | ); 136 | name = Products; 137 | sourceTree = ""; 138 | }; 139 | 41E2BAD61FA31B9C0086BA89 /* MCTableViewManagerExample */ = { 140 | isa = PBXGroup; 141 | children = ( 142 | 41CE55F221143B0A0081F3A9 /* Controller */, 143 | 41CE55F121143AFF0081F3A9 /* View */, 144 | 41E2BADA1FA31B9D0086BA89 /* ViewController.h */, 145 | 41E2BADB1FA31B9D0086BA89 /* ViewController.m */, 146 | 41E2BAED1FA31C080086BA89 /* MCTableViewManager */, 147 | 41E2BAD71FA31B9C0086BA89 /* AppDelegate.h */, 148 | 41E2BAD81FA31B9D0086BA89 /* AppDelegate.m */, 149 | 41E2BAE01FA31B9D0086BA89 /* Assets.xcassets */, 150 | 41E2BAE21FA31B9D0086BA89 /* LaunchScreen.storyboard */, 151 | 41E2BAE51FA31B9D0086BA89 /* Info.plist */, 152 | 41E2BAE61FA31B9D0086BA89 /* main.m */, 153 | ); 154 | path = MCTableViewManagerExample; 155 | sourceTree = ""; 156 | }; 157 | 41E2BAED1FA31C080086BA89 /* MCTableViewManager */ = { 158 | isa = PBXGroup; 159 | children = ( 160 | 41E2BAEE1FA31C080086BA89 /* MCBaseDataModel.h */, 161 | 41E2BAEF1FA31C080086BA89 /* MCBaseDataModel.m */, 162 | 41E2BAF01FA31C080086BA89 /* MCTableViewManager.h */, 163 | 41E2BAF11FA31C080086BA89 /* MCTableViewManager.m */, 164 | 41CE55EE21143AAA0081F3A9 /* MCTableViewDelegate.h */, 165 | 41CE55EF21143AAA0081F3A9 /* MCTableViewDelegate.m */, 166 | 41AEDA91211AD73900208023 /* MCBaseHeaderFooterDataModel.h */, 167 | 41AEDA92211AD73900208023 /* MCBaseHeaderFooterDataModel.m */, 168 | ); 169 | name = MCTableViewManager; 170 | path = ../../MCTableViewManager; 171 | sourceTree = ""; 172 | }; 173 | /* End PBXGroup section */ 174 | 175 | /* Begin PBXNativeTarget section */ 176 | 4118E7532112F60A007C577A /* MCTableViewManagerExampleTests */ = { 177 | isa = PBXNativeTarget; 178 | buildConfigurationList = 4118E75B2112F60B007C577A /* Build configuration list for PBXNativeTarget "MCTableViewManagerExampleTests" */; 179 | buildPhases = ( 180 | 4118E7502112F60A007C577A /* Sources */, 181 | 4118E7512112F60A007C577A /* Frameworks */, 182 | 4118E7522112F60A007C577A /* Resources */, 183 | ); 184 | buildRules = ( 185 | ); 186 | dependencies = ( 187 | 4118E75A2112F60B007C577A /* PBXTargetDependency */, 188 | ); 189 | name = MCTableViewManagerExampleTests; 190 | productName = MCTableViewManagerExampleTests; 191 | productReference = 4118E7542112F60B007C577A /* MCTableViewManagerExampleTests.xctest */; 192 | productType = "com.apple.product-type.bundle.unit-test"; 193 | }; 194 | 41E2BAD31FA31B9C0086BA89 /* MCTableViewManagerExample */ = { 195 | isa = PBXNativeTarget; 196 | buildConfigurationList = 41E2BAEA1FA31B9D0086BA89 /* Build configuration list for PBXNativeTarget "MCTableViewManagerExample" */; 197 | buildPhases = ( 198 | 41E2BAD01FA31B9C0086BA89 /* Sources */, 199 | 41E2BAD11FA31B9C0086BA89 /* Frameworks */, 200 | 41E2BAD21FA31B9C0086BA89 /* Resources */, 201 | ); 202 | buildRules = ( 203 | ); 204 | dependencies = ( 205 | ); 206 | name = MCTableViewManagerExample; 207 | productName = MCTableViewManagerExample; 208 | productReference = 41E2BAD41FA31B9C0086BA89 /* MCTableViewManagerExample.app */; 209 | productType = "com.apple.product-type.application"; 210 | }; 211 | /* End PBXNativeTarget section */ 212 | 213 | /* Begin PBXProject section */ 214 | 41E2BACC1FA31B9C0086BA89 /* Project object */ = { 215 | isa = PBXProject; 216 | attributes = { 217 | LastUpgradeCheck = 0900; 218 | ORGANIZATIONNAME = "marco chen"; 219 | TargetAttributes = { 220 | 4118E7532112F60A007C577A = { 221 | CreatedOnToolsVersion = 9.4; 222 | ProvisioningStyle = Automatic; 223 | TestTargetID = 41E2BAD31FA31B9C0086BA89; 224 | }; 225 | 41E2BAD31FA31B9C0086BA89 = { 226 | CreatedOnToolsVersion = 9.0; 227 | ProvisioningStyle = Automatic; 228 | }; 229 | }; 230 | }; 231 | buildConfigurationList = 41E2BACF1FA31B9C0086BA89 /* Build configuration list for PBXProject "MCTableViewManagerExample" */; 232 | compatibilityVersion = "Xcode 8.0"; 233 | developmentRegion = en; 234 | hasScannedForEncodings = 0; 235 | knownRegions = ( 236 | en, 237 | Base, 238 | ); 239 | mainGroup = 41E2BACB1FA31B9C0086BA89; 240 | productRefGroup = 41E2BAD51FA31B9C0086BA89 /* Products */; 241 | projectDirPath = ""; 242 | projectRoot = ""; 243 | targets = ( 244 | 41E2BAD31FA31B9C0086BA89 /* MCTableViewManagerExample */, 245 | 4118E7532112F60A007C577A /* MCTableViewManagerExampleTests */, 246 | ); 247 | }; 248 | /* End PBXProject section */ 249 | 250 | /* Begin PBXResourcesBuildPhase section */ 251 | 4118E7522112F60A007C577A /* Resources */ = { 252 | isa = PBXResourcesBuildPhase; 253 | buildActionMask = 2147483647; 254 | files = ( 255 | ); 256 | runOnlyForDeploymentPostprocessing = 0; 257 | }; 258 | 41E2BAD21FA31B9C0086BA89 /* Resources */ = { 259 | isa = PBXResourcesBuildPhase; 260 | buildActionMask = 2147483647; 261 | files = ( 262 | 41E2BAE41FA31B9D0086BA89 /* LaunchScreen.storyboard in Resources */, 263 | 41E2BAE11FA31B9D0086BA89 /* Assets.xcassets in Resources */, 264 | ); 265 | runOnlyForDeploymentPostprocessing = 0; 266 | }; 267 | /* End PBXResourcesBuildPhase section */ 268 | 269 | /* Begin PBXSourcesBuildPhase section */ 270 | 4118E7502112F60A007C577A /* Sources */ = { 271 | isa = PBXSourcesBuildPhase; 272 | buildActionMask = 2147483647; 273 | files = ( 274 | 4118E7572112F60B007C577A /* MCTableViewManagerExampleTests.m in Sources */, 275 | ); 276 | runOnlyForDeploymentPostprocessing = 0; 277 | }; 278 | 41E2BAD01FA31B9C0086BA89 /* Sources */ = { 279 | isa = PBXSourcesBuildPhase; 280 | buildActionMask = 2147483647; 281 | files = ( 282 | 41CE55ED211422C80081F3A9 /* FuncInitExampleController.m in Sources */, 283 | 41E2BAF21FA31CFC0086BA89 /* MCBaseDataModel.m in Sources */, 284 | 41CE55E7211303570081F3A9 /* CTableViewCell.m in Sources */, 285 | 41E2BAF31FA31CFD0086BA89 /* MCTableViewManager.m in Sources */, 286 | 41CE55F021143AAA0081F3A9 /* MCTableViewDelegate.m in Sources */, 287 | 41E2BAF61FA31DDF0086BA89 /* AExampleCell.m in Sources */, 288 | 41E2BADC1FA31B9D0086BA89 /* ViewController.m in Sources */, 289 | 41CE55EA21141F060081F3A9 /* InstanceExampleController.m in Sources */, 290 | 41E2BAE71FA31B9D0086BA89 /* main.m in Sources */, 291 | 41E2BAF91FA31DF20086BA89 /* BExampleCell.m in Sources */, 292 | 41AEDA93211AD73900208023 /* MCBaseHeaderFooterDataModel.m in Sources */, 293 | 41E2BAD91FA31B9D0086BA89 /* AppDelegate.m in Sources */, 294 | ); 295 | runOnlyForDeploymentPostprocessing = 0; 296 | }; 297 | /* End PBXSourcesBuildPhase section */ 298 | 299 | /* Begin PBXTargetDependency section */ 300 | 4118E75A2112F60B007C577A /* PBXTargetDependency */ = { 301 | isa = PBXTargetDependency; 302 | target = 41E2BAD31FA31B9C0086BA89 /* MCTableViewManagerExample */; 303 | targetProxy = 4118E7592112F60B007C577A /* PBXContainerItemProxy */; 304 | }; 305 | /* End PBXTargetDependency section */ 306 | 307 | /* Begin PBXVariantGroup section */ 308 | 41E2BAE21FA31B9D0086BA89 /* LaunchScreen.storyboard */ = { 309 | isa = PBXVariantGroup; 310 | children = ( 311 | 41E2BAE31FA31B9D0086BA89 /* Base */, 312 | ); 313 | name = LaunchScreen.storyboard; 314 | sourceTree = ""; 315 | }; 316 | /* End PBXVariantGroup section */ 317 | 318 | /* Begin XCBuildConfiguration section */ 319 | 4118E75C2112F60B007C577A /* Debug */ = { 320 | isa = XCBuildConfiguration; 321 | buildSettings = { 322 | BUNDLE_LOADER = "$(TEST_HOST)"; 323 | CLANG_ENABLE_OBJC_WEAK = YES; 324 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 325 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 326 | CODE_SIGN_STYLE = Automatic; 327 | DEVELOPMENT_TEAM = X7ZHUDCZT7; 328 | INFOPLIST_FILE = MCTableViewManagerExampleTests/Info.plist; 329 | IPHONEOS_DEPLOYMENT_TARGET = 11.4; 330 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 331 | PRODUCT_BUNDLE_IDENTIFIER = "marco-chen.MCTableViewManagerExampleTests"; 332 | PRODUCT_NAME = "$(TARGET_NAME)"; 333 | TARGETED_DEVICE_FAMILY = "1,2"; 334 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MCTableViewManagerExample.app/MCTableViewManagerExample"; 335 | }; 336 | name = Debug; 337 | }; 338 | 4118E75D2112F60B007C577A /* Release */ = { 339 | isa = XCBuildConfiguration; 340 | buildSettings = { 341 | BUNDLE_LOADER = "$(TEST_HOST)"; 342 | CLANG_ENABLE_OBJC_WEAK = YES; 343 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 344 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 345 | CODE_SIGN_STYLE = Automatic; 346 | DEVELOPMENT_TEAM = X7ZHUDCZT7; 347 | INFOPLIST_FILE = MCTableViewManagerExampleTests/Info.plist; 348 | IPHONEOS_DEPLOYMENT_TARGET = 11.4; 349 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 350 | PRODUCT_BUNDLE_IDENTIFIER = "marco-chen.MCTableViewManagerExampleTests"; 351 | PRODUCT_NAME = "$(TARGET_NAME)"; 352 | TARGETED_DEVICE_FAMILY = "1,2"; 353 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/MCTableViewManagerExample.app/MCTableViewManagerExample"; 354 | }; 355 | name = Release; 356 | }; 357 | 41E2BAE81FA31B9D0086BA89 /* Debug */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | ALWAYS_SEARCH_USER_PATHS = NO; 361 | CLANG_ANALYZER_NONNULL = YES; 362 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 363 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 364 | CLANG_CXX_LIBRARY = "libc++"; 365 | CLANG_ENABLE_MODULES = YES; 366 | CLANG_ENABLE_OBJC_ARC = YES; 367 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 368 | CLANG_WARN_BOOL_CONVERSION = YES; 369 | CLANG_WARN_COMMA = YES; 370 | CLANG_WARN_CONSTANT_CONVERSION = YES; 371 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 372 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 373 | CLANG_WARN_EMPTY_BODY = YES; 374 | CLANG_WARN_ENUM_CONVERSION = YES; 375 | CLANG_WARN_INFINITE_RECURSION = YES; 376 | CLANG_WARN_INT_CONVERSION = YES; 377 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 378 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 379 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 380 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 381 | CLANG_WARN_STRICT_PROTOTYPES = YES; 382 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 383 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 384 | CLANG_WARN_UNREACHABLE_CODE = YES; 385 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 386 | CODE_SIGN_IDENTITY = "iPhone Developer"; 387 | COPY_PHASE_STRIP = NO; 388 | DEBUG_INFORMATION_FORMAT = dwarf; 389 | ENABLE_STRICT_OBJC_MSGSEND = YES; 390 | ENABLE_TESTABILITY = YES; 391 | GCC_C_LANGUAGE_STANDARD = gnu11; 392 | GCC_DYNAMIC_NO_PIC = NO; 393 | GCC_NO_COMMON_BLOCKS = YES; 394 | GCC_OPTIMIZATION_LEVEL = 0; 395 | GCC_PREPROCESSOR_DEFINITIONS = ( 396 | "DEBUG=1", 397 | "$(inherited)", 398 | ); 399 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 400 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 401 | GCC_WARN_UNDECLARED_SELECTOR = YES; 402 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 403 | GCC_WARN_UNUSED_FUNCTION = YES; 404 | GCC_WARN_UNUSED_VARIABLE = YES; 405 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 406 | MTL_ENABLE_DEBUG_INFO = YES; 407 | ONLY_ACTIVE_ARCH = YES; 408 | SDKROOT = iphoneos; 409 | }; 410 | name = Debug; 411 | }; 412 | 41E2BAE91FA31B9D0086BA89 /* Release */ = { 413 | isa = XCBuildConfiguration; 414 | buildSettings = { 415 | ALWAYS_SEARCH_USER_PATHS = NO; 416 | CLANG_ANALYZER_NONNULL = YES; 417 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 418 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; 419 | CLANG_CXX_LIBRARY = "libc++"; 420 | CLANG_ENABLE_MODULES = YES; 421 | CLANG_ENABLE_OBJC_ARC = YES; 422 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 423 | CLANG_WARN_BOOL_CONVERSION = YES; 424 | CLANG_WARN_COMMA = YES; 425 | CLANG_WARN_CONSTANT_CONVERSION = YES; 426 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 427 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 428 | CLANG_WARN_EMPTY_BODY = YES; 429 | CLANG_WARN_ENUM_CONVERSION = YES; 430 | CLANG_WARN_INFINITE_RECURSION = YES; 431 | CLANG_WARN_INT_CONVERSION = YES; 432 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 433 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 434 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 435 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 436 | CLANG_WARN_STRICT_PROTOTYPES = YES; 437 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 438 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 439 | CLANG_WARN_UNREACHABLE_CODE = YES; 440 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 441 | CODE_SIGN_IDENTITY = "iPhone Developer"; 442 | COPY_PHASE_STRIP = NO; 443 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 444 | ENABLE_NS_ASSERTIONS = NO; 445 | ENABLE_STRICT_OBJC_MSGSEND = YES; 446 | GCC_C_LANGUAGE_STANDARD = gnu11; 447 | GCC_NO_COMMON_BLOCKS = YES; 448 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 449 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 450 | GCC_WARN_UNDECLARED_SELECTOR = YES; 451 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 452 | GCC_WARN_UNUSED_FUNCTION = YES; 453 | GCC_WARN_UNUSED_VARIABLE = YES; 454 | IPHONEOS_DEPLOYMENT_TARGET = 11.0; 455 | MTL_ENABLE_DEBUG_INFO = NO; 456 | SDKROOT = iphoneos; 457 | VALIDATE_PRODUCT = YES; 458 | }; 459 | name = Release; 460 | }; 461 | 41E2BAEB1FA31B9D0086BA89 /* Debug */ = { 462 | isa = XCBuildConfiguration; 463 | buildSettings = { 464 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 465 | CODE_SIGN_STYLE = Automatic; 466 | DEVELOPMENT_TEAM = X7ZHUDCZT7; 467 | INFOPLIST_FILE = MCTableViewManagerExample/Info.plist; 468 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 469 | PRODUCT_BUNDLE_IDENTIFIER = "marco-chen.MCTableViewManagerExample"; 470 | PRODUCT_NAME = "$(TARGET_NAME)"; 471 | TARGETED_DEVICE_FAMILY = "1,2"; 472 | }; 473 | name = Debug; 474 | }; 475 | 41E2BAEC1FA31B9D0086BA89 /* Release */ = { 476 | isa = XCBuildConfiguration; 477 | buildSettings = { 478 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 479 | CODE_SIGN_STYLE = Automatic; 480 | DEVELOPMENT_TEAM = X7ZHUDCZT7; 481 | INFOPLIST_FILE = MCTableViewManagerExample/Info.plist; 482 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 483 | PRODUCT_BUNDLE_IDENTIFIER = "marco-chen.MCTableViewManagerExample"; 484 | PRODUCT_NAME = "$(TARGET_NAME)"; 485 | TARGETED_DEVICE_FAMILY = "1,2"; 486 | }; 487 | name = Release; 488 | }; 489 | /* End XCBuildConfiguration section */ 490 | 491 | /* Begin XCConfigurationList section */ 492 | 4118E75B2112F60B007C577A /* Build configuration list for PBXNativeTarget "MCTableViewManagerExampleTests" */ = { 493 | isa = XCConfigurationList; 494 | buildConfigurations = ( 495 | 4118E75C2112F60B007C577A /* Debug */, 496 | 4118E75D2112F60B007C577A /* Release */, 497 | ); 498 | defaultConfigurationIsVisible = 0; 499 | defaultConfigurationName = Release; 500 | }; 501 | 41E2BACF1FA31B9C0086BA89 /* Build configuration list for PBXProject "MCTableViewManagerExample" */ = { 502 | isa = XCConfigurationList; 503 | buildConfigurations = ( 504 | 41E2BAE81FA31B9D0086BA89 /* Debug */, 505 | 41E2BAE91FA31B9D0086BA89 /* Release */, 506 | ); 507 | defaultConfigurationIsVisible = 0; 508 | defaultConfigurationName = Release; 509 | }; 510 | 41E2BAEA1FA31B9D0086BA89 /* Build configuration list for PBXNativeTarget "MCTableViewManagerExample" */ = { 511 | isa = XCConfigurationList; 512 | buildConfigurations = ( 513 | 41E2BAEB1FA31B9D0086BA89 /* Debug */, 514 | 41E2BAEC1FA31B9D0086BA89 /* Release */, 515 | ); 516 | defaultConfigurationIsVisible = 0; 517 | defaultConfigurationName = Release; 518 | }; 519 | /* End XCConfigurationList section */ 520 | }; 521 | rootObject = 41E2BACC1FA31B9C0086BA89 /* Project object */; 522 | } 523 | --------------------------------------------------------------------------------