今天要说的是一种代码优化的技巧,我们知道,编程一直讲求高聚合,低耦合。一般地,我们会将一个页面的UITableviewDelegate
和UITableviewDataSource
写在同一个controller里,如果你只有一个数据源,这样写是可以的。但假设下面这种情况,如图,一个页面有多个数据源,如果在同一个controller里写的话,一个controller同时要遵守UITableViewDelegate,UITableviewDataSource,UICollectionDelegate,UICollectionDataSource,
然后将这些代理实现,那controller的压力是不是会变得很大呢?接下来就是减压的时刻了。
先看下项目中的效果图。
下面以图中左边的tableview为例。
先建一个类继承自
NSObject
,遵循UITableviewDataSource
,并定义一个block,写两个对象方法,定义一个数组,代码如下:
XSMutiCatagoryTableviewDataSource.h
#import <UIKit/UIKit.h>
typedef void (^MutiCatagoryTableViewCellConfigureBlock)(id cell, id item);
@interface XSMutiCatagoryTableViewDataSource : NSObject <UITableViewDataSource>
@property (nonatomic, copy) NSArray *items;
- (id)initWithItems:(NSArray *)items cellIdentifier:(NSString *)cellIdentifier configureCellBlock:(MutiCatagoryTableViewCellConfigureBlock)configureCellBlock;
- (id)itemAtIndexPath:(NSIndexPath *)indexPath;
@end
XSMutiCatagoryTableviewDataSource.m
#import "XSMutiCatagoryTableViewDataSource.h"
@interface XSMutiCatagoryTableViewDataSource ()
@property (nonatomic, copy) NSString *cellIdentifier;
@property (nonatomic, copy) MutiCatagoryTableViewCellConfigureBlock configureCellBlock;
@end
@implementation XSMutiCatagoryTableViewDataSource
- (id)initWithItems:(NSArray *)items cellIdentifier:(NSString *)cellIdentifier configureCellBlock:(MutiCatagoryTableViewCellConfigureBlock)configureCellBlock {
self = [super init];
if (self) {
self.items = items;
self.cellIdentifier = cellIdentifier;
self.configureCellBlock = configureCellBlock;
}
return self;
}
#pragma mark - public methods
- (id)itemAtIndexPath:(NSIndexPath *)indexPath {
return self.items[(NSUInteger)indexPath.row];
}
#pragma mark - UITableViewDataSource
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.items count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:self.cellIdentifier forIndexPath:indexPath];
id item = [self itemAtIndexPath:indexPath];
self.configureCellBlock(cell, item);
return cell;
}
@end
然后就是controller里的事情了
XSMutiCatagoryViewController.m
#import "XSMutiCatagoryTableViewDataSource.h"
@interface XSMutiCatagoryViewController () <UITableViewDelegate>
@property (strong, nonatomic) XSMutiCatagoryTableViewDataSource *mutiCatagoryTableViewDataSource;
@property (strong, nonatomic) UITableView *tableView;
@property (strong, nonatomic) MenuBridge *menuBridge;//数据源
@end
@implementation XSMutiCatagoryViewController
#pragma mark - life cycle
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
CGFloat height = [UIScreen mainScreen].bounds.size.height;
CGFloat width = [UIScreen mainScreen].bounds.size.width;
self.tableView.frame = CGRectMake(0,64, width / 4, height-49-64);
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:self.tableView];
[self loadMenuData];
}
#pragma mark - http menthods
- (void)loadMenuData {
__weak typeof(self) weakSelf = self;
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
XSAPIManager *manager = [XSAPIManager manager];
[manager GET:url parameters:parameters success:^(id responseObject) {
//NSLog(@"分类页tableview数据%@",responseObject);
weakSelf.menuBridge = [MenuBridge mj_objectWithKeyValues:responseObject];
if (weakSelf.menuBridge.data.count > 0) {
weakSelf.mutiCatagoryTableViewDataSource.items = weakSelf.menuBridge.data;
[weakSelf.tableView reloadData];
[weakSelf.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] animated:YES scrollPosition:UITableViewScrollPositionBottom];
[weakSelf tableView:weakSelf.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
}
[MBProgressHUD hideAllHUDsForView:weakSelf.view animated:YES];
} failure:^(NSError *error) {
[MBProgressHUD hideAllHUDsForView:weakSelf.view animated:YES];
}];
}
#pragma mark - getters and setters
- (UITableView *)tableView {
if (_tableView == nil) {
_tableView = [[UITableView alloc] init];
_tableView.backgroundColor = MENU_COLOR;
_tableView.separatorColor = OTHER_SEPARATOR_COLOR;
[_tableView registerNib:[UINib nibWithNibName:@"XSMutiCatagoryTableViewCell" bundle:nil] forCellReuseIdentifier:tableCellId];
_tableView.delegate = self;
_tableView.dataSource = self.mutiCatagoryTableViewDataSource;
_tableView.rowHeight = 49.0f;
}
return _tableView;
}
- (XSMutiCatagoryTableViewDataSource *)mutiCatagoryTableViewDataSource {
if (_mutiCatagoryTableViewDataSource == nil) {
_mutiCatagoryTableViewDataSource = [[XSMutiCatagoryTableViewDataSource alloc] initWithItems:self.menuBridge.data cellIdentifier:tableCellId configureCellBlock:^(XSMutiCatagoryTableViewCell *cell, Menu *item) {
[cell configureForMenuItem:item];
}];
}
return _mutiCatagoryTableViewDataSource;
}
以上。