UI总结之UITableView的封装和类的交互1中实现了简单的滚动视图的封装和类的交互,接下来就是封装表视图的过程了,我们可以从创建一个nib文件来创建一个容器视图。其实我们逻辑的搭建是由小到大,笼统来说就是我们先封装了滚动视图,然后再封装表视图,将滚动视图加到表视图中!
@interface YXContentView () <UITableViewDataSource,UITableViewDelegate>
@property (weak, nonatomic) IBOutlet UITableView *tableView;
@end
@implementation YXContentView
// 只要当前的对象从xib文件加载过来,会默认调用这个方法 - awakeFromNib
// 我们可以在这里设置一些初始化的属性
- (void)awakeFromNib {
// 封装好的滚动视图
YXADSView *adsView = [YXADSView adsView];
self.tableView.tableHeaderView = adsView;
NSArray *images = @[@"ad_00",@"ad_01",@"ad_02",@"ad_03",@"ad_04"];
adsView.images = images;
self.tableView.rowHeight = 100;
}
- (void)setDataArray:(NSMutableArray *)dataArray {
// 更新子控件的中的数据
// 容器视图从控制器得到数据,直接给予表视图 让它加载数据
_dataArray = dataArray;
[self.tableView reloadData];
}
+ (id)contentView {
return [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass([self class]) owner:nil options:nil] lastObject];
}
#pragma mark - UITableView 数据源方法
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return self.dataArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
YXCustomCell *cell = [YXCustomCell customCellWithTableView:tableView];
cell.model = self.dataArray[indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[_delegate contentViewCellDidSelected:self model:self.dataArray[indexPath.row] index:indexPath.row];
if (self.myBlock) {
self.myBlock(self,self.dataArray[indexPath.row],indexPath.row);
}
}
- (void)contentViewCellDidSeletedWithBlock:(contentViewCellDidSelectedBlock)block {
self.myBlock = block;
}
表视图的实现就很简单了,只需要将封装好的视图添加到表视图中,然后表视图本身从控制器得到数据模型展示数据,设置代理或者block来完成类与类之间的交互,
typedef void(^contentViewCellDidSelectedBlock)(YXContentView * contentView, YXModels *models,NSInteger index);
@protocol YXContentViewDelegate <NSObject>
- (void)contentViewCellDidSelected:(YXContentView *)contentView
model:(YXModels *)model
index:(NSInteger)index;
@end
@interface YXContentView : UIView
@property (nonatomic,strong) NSMutableArray *dataArray;
@property (nonatomic,assign) id <YXContentViewDelegate> delegate;
@property (nonatomic,copy) contentViewCellDidSelectedBlock myBlock;
+ (id)contentView;
- (void)contentViewCellDidSeletedWithBlock:(void(^)(YXContentView * contentView, YXModels *models,NSInteger index))block;
我们可以在cell的点击代理方法中,将数据模型或者其他东西交给我们自定义的代理或者block去通信,这样我们的逻辑性就非常清晰了。注意点是在声明协议方法的时候最好规范书写,遵循系统书写协议的规范,这是一个良好的习惯。block相比代理来说更加灵活,它可以被声明为一个属性,只要block的地址已经在类与类之间得到了确认或者说是类与类之间的通信连接已经建立,我们可以随时调用block,一般情况下,我们可以声明方法将block代码块作为参数传递,这样写起来更加方便。