上一篇簡述了基于MVC設計模式對UITableView使用,本篇基于MVVM模式繼續練習使用UITableView。
UITableView具體屬性及方法可以參考文章:UITableView簡介
UITableView簡單使用可以參考文章:UITableView使用練習
MVVM設計模式簡介可以參考文章:MVVM設計模式簡介
寫了個簡單的例子,控制器繼承UITableViewController,不需要再去手動添加協定,設定代理。遵循MVVM設計模式,自定義頭部視圖、Cell、Model、viewModel,效果如圖33-1:
下面貼上代碼:
HWTableViewController:
#import <UIKit/UIKit.h>
@interface HWTableViewController : UITableViewController
@end
#import "HWTableViewController.h"
#import "HWHeaderView.h"
#import "HWTableViewCell.h"
#import "HWCellViewModel.h"
@interface HWTableViewController ()
@property (nonatomic, strong) HWCellViewModel *viewModel;
@end
@implementation HWTableViewController
- (void)viewDidLoad {
[super viewDidLoad];
//建立頭部視圖
self.tableView.tableHeaderView = [[HWHeaderView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 100)];
self.viewModel = [[HWCellViewModel alloc] init];
}
#pragma mark - Table view data source
//組數
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [self.viewModel numberOfSections];
}
//組中行數
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return [self.viewModel numberOfItemsInSection:section];
}
//cell内容
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [self.viewModel tableView:tableView cellForRowAtIndexPath:indexPath];
}
//點選事件
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.viewModel tableView:tableView didSelectRowAtIndexPath:indexPath];
}
//設定行高
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return [self.viewModel tableView:tableView heightForRowAtIndexPath:indexPath];
}
//設定頭部标題
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
return [self.viewModel titleForHeaderInSection:section];
}
//設定尾部标題
- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
{
return [self.viewModel titleForFooterInSection:section];
}
@end
HWHeaderView:
#import <UIKit/UIKit.h>
@interface HWHeaderView : UIView
@end
#import "HWHeaderView.h"
@implementation HWHeaderView
//重寫init方法
- (id)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
//建立一個标簽作為頭部視圖
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 100)];
label.text = @"這是頭部視圖";
label.textAlignment = NSTextAlignmentCenter;
label.textColor = [UIColor whiteColor];
label.backgroundColor = [UIColor grayColor];
[self addSubview:label];
}
return self;
}
@end
HWTableViewCell:
#import <UIKit/UIKit.h>
@class HWCellModel;
@interface HWTableViewCell : UITableViewCell
@property (nonatomic, weak) UILabel *lable;
@property (nonatomic, strong) HWCellModel *model;
+ (instancetype)cellWIthTableView:(UITableView *)tableView;
@end
#import "HWTableViewCell.h"
#import "HWCellModel.h"
@interface HWTableViewCell ()
@property (nonatomic, weak) UIImageView *imgView;
@property (nonatomic, weak) UILabel *subLabel;
@end
@implementation HWTableViewCell
+ (instancetype)cellWIthTableView:(UITableView *)tableView
{
//cell複用,唯一辨別
static NSString *identifier = @"HWCell";
//先在緩存池中取
HWTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
//緩存池中沒有再建立,并添加辨別,cell移出螢幕時放入緩存池以複用
if (cell == nil) {
cell = [[HWTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}
return cell;
}
//重寫init方法建構cell内容
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
//圖檔
UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 80, 60)];
[self.contentView addSubview:imageView];
self.imgView = imageView;
//标題
UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(imageView.frame) + 10, 15, 200, 20)];
label.font = [UIFont systemFontOfSize:20.0f];
[self.contentView addSubview:label];
self.lable = label;
//副标題
UILabel *subLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(imageView.frame) + 10, 40, 200, 13)];
subLabel.font = [UIFont systemFontOfSize:13.0f];
[self.contentView addSubview:subLabel];
self.subLabel = subLabel;
self.backgroundColor = [UIColor whiteColor];
}
return self;
}
//重寫set方法,模型傳遞
- (void)setModel:(HWCellModel *)model
{
_model = model;
self.imgView.image = [UIImage imageNamed:model.image];
self.lable.text = model.title;
self.subLabel.text = model.subTitle;
}
@end
HWCellModel:
#import <Foundation/Foundation.h>
@interface HWCellModel : NSObject
@property (nonatomic, copy) NSString *image;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subTitle;
- (id)initWithDictionary:(NSDictionary *)dict;
+ (id)HWInfoWithDictionary:(NSDictionary *)dict;
@end
#import "HWCellModel.h"
@implementation HWCellModel
- (id)initWithDictionary:(NSDictionary *)dict
{
self = [super init];
if (self) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
+ (id)HWInfoWithDictionary:(NSDictionary *)dict
{
return [[self alloc] initWithDictionary:dict];
}
@end
HWCellViewModel:
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@class HWTableViewCell, UITableView;
@interface HWCellViewModel : NSObject
@property (nonatomic, strong) NSMutableArray *HWInfoArray;
- (NSInteger)numberOfSections;
- (NSInteger)numberOfItemsInSection:(NSInteger)section;
- (NSString *)titleForHeaderInSection:(NSInteger)section;
- (NSString *)titleForFooterInSection:(NSInteger)section;
- (HWTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
@end
#import "HWCellViewModel.h"
#import "HWCellModel.h"
#import "HWTableViewCell.h"
@implementation HWCellViewModel
- (NSMutableArray *)HWInfoArray
{
if (_HWInfoArray == nil) {
_HWInfoArray = [NSMutableArray array];
}
return _HWInfoArray;
}
- (instancetype)init
{
self = [super init];
if (self) {
[self getInfo];
}
return self;
}
- (void)getInfo
{
//實際開發資料是網絡擷取到的,這裡模拟給出一個資料
NSArray *array = @[@[@{@"image" : @"hero", @"title" : @"标題1", @"subTitle" : @"副标題1"},
@{@"image" : @"hero", @"title" : @"标題2", @"subTitle" : @"副标題2"}],
@[@{@"image" : @"hero", @"title" : @"标題3", @"subTitle" : @"副标題3"},
@{@"image" : @"hero", @"title" : @"标題4", @"subTitle" : @"副标題4"},
@{@"image" : @"hero", @"title" : @"标題5", @"subTitle" : @"副标題5"},
@{@"image" : @"hero", @"title" : @"标題6", @"subTitle" : @"副标題6"},
@{@"image" : @"hero", @"title" : @"标題7", @"subTitle" : @"副标題7"}]];
//解析資料,轉模型儲存
for (int i = 0; i < array.count; i++) {
NSMutableArray *tempArray = [NSMutableArray array];
for (NSDictionary *dict in array[i]) {
[tempArray addObject:[HWCellModel HWInfoWithDictionary:dict]];
}
[self.HWInfoArray addObject:tempArray];
}
}
- (NSInteger)numberOfSections
{
return self.HWInfoArray.count;
}
- (NSInteger)numberOfItemsInSection:(NSInteger)section
{
return [self.HWInfoArray[section] count];
}
- (HWTableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
HWTableViewCell *cell = [HWTableViewCell cellWIthTableView:tableView];
cell.model = self.HWInfoArray[indexPath.section][indexPath.row];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
//擷取到目前被點選的cell
HWTableViewCell *cell = (HWTableViewCell *)[tableView cellForRowAtIndexPath:indexPath];
NSString *str = [NSString stringWithFormat:@"點選了第%ld組第%ld行", indexPath.section, indexPath.row];
cell.lable.text = str;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 70.0f;
}
- (NSString *)titleForHeaderInSection:(NSInteger)section
{
if (section == 0) {
return @"第一組";
}
return @"第二組";
}
- (NSString *)titleForFooterInSection:(NSInteger)section
{
return @"這是尾部标題";
}
@end