iOS-UI基础(自定义TableViewCell)

一.纯代码自定义Cell(使用MJExtension和Masonry)

纯代码自定义一个tableViewCell的步骤

1.新建一个继承自UITableViewCell的类

2.重写initWithStyle:reuseIdentifier:方法

添加所有需要显示的子控件(不需要设置子控件的数据和frame,  子控件要添加到contentView中)

进行子控件一次性的属性设置(有些属性只需要设置一次, 比如字体\固定的图片)

3.提供2个模型

数据模型: 存放文字数据\图片数据

frame模型: 存放数据模型\所有子控件的frame\cell的高度

4.cell拥有一个frame模型(不要直接拥有数据模型)

5.重写frame模型属性的setter方法: 在这个方法中设置子控件的显示数据和frame 

6.frame模型数据的初始化已经采取懒加载的方式(每一个cell对应的frame模型数据只加载一次)

1.模型代码如下:

//  XMGTg.h

#import 

@interface XMGTg : NSObject
/** 图标 */
@property (nonatomic, copy) NSString *icon;

/** 标题 */
@property (nonatomic, copy) NSString *title;

/** 价格 */
@property (nonatomic, copy) NSString *price;

/** 购买数 */
@property (nonatomic, copy) NSString *buyCount;

//+ (instancetype)tgWithDict:(NSDictionary *)dict;
@end
//  XMGTg.m

#import "XMGTg.h"

@implementation XMGTg
//+ (instancetype)tgWithDict:(NSDictionary *)dict
//{
//    XMGTg *tg = [[self alloc] init];
//    [tg setValuesForKeysWithDictionary:dict];
//    return tg;
//}
@end
注意:使用MJExtension之后就不用写字典转模型方法了


2.Cell代码如下:

//  XMGTgCell.h

#import 

@class XMGTg;
@interface XMGTgCell : UITableViewCell

/** 团购模型 */
@property (nonatomic, strong) XMGTg *tg;
@end
//  XMGTgCell.m

#import "XMGTgCell.h"
#import "XMGTg.h"

//define this constant if you want to use Masonry without the 'mas_' prefix
#define MAS_SHORTHAND

//define this constant if you want to enable auto-boxing for default syntax
#define MAS_SHORTHAND_GLOBALS
#import "Masonry.h"

@interface XMGTgCell ()
/** 图标 */
@property (nonatomic, weak) UIImageView *iconImageView;

/** 标题 */
@property (nonatomic, weak) UILabel *titleLabel;

/** 价格 */
@property (nonatomic, weak) UILabel *priceLabel;

/** 购买数 */
@property (nonatomic, weak) UILabel *buyCountLabel;
@end

@implementation XMGTgCell

// 在这个方法中添加所有的子控件
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
        CGFloat spcae = 10;
        /** 图标 */
        UIImageView *iconImageView = [[UIImageView alloc] init];
        [self.contentView addSubview:iconImageView];
        self.iconImageView = iconImageView;
        [iconImageView makeConstraints:^(MASConstraintMaker *make) {
            make.top.left.equalTo(self.contentView).offset(spcae);
            make.bottom.equalTo(self.contentView).offset(-spcae);
            make.width.equalTo(80);
        }];

        /** 标题 */
        UILabel *titleLabel = [[UILabel alloc] init];
        [self.contentView addSubview:titleLabel];
        self.titleLabel = titleLabel;
        [titleLabel makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(iconImageView.top);
            make.left.equalTo(iconImageView.right).offset(spcae);
            make.right.equalTo(self.contentView).offset(-spcae);
            make.height.equalTo(20);
        }];
        
        /** 价格 */
        UILabel *priceLabel = [[UILabel alloc] init];
        priceLabel.textColor = [UIColor orangeColor];
        priceLabel.font = [UIFont systemFontOfSize:15];
        [self.contentView addSubview:priceLabel];
        self.priceLabel = priceLabel;
        [priceLabel makeConstraints:^(MASConstraintMaker *make) {
            make.left.equalTo(titleLabel.left);
            make.bottom.equalTo(iconImageView.bottom);
            make.size.equalTo(CGSizeMake(100, 15));
        }];
        
        /** 购买数 */
        UILabel *buyCountLabel = [[UILabel alloc] init];
        buyCountLabel.textAlignment = NSTextAlignmentRight;
        buyCountLabel.textColor = [UIColor lightGrayColor];
        buyCountLabel.font = [UIFont systemFontOfSize:14];
        [self.contentView addSubview:buyCountLabel];
        self.buyCountLabel = buyCountLabel;
        [buyCountLabel makeConstraints:^(MASConstraintMaker *make) {
            make.bottom.equalTo(iconImageView.bottom);
            make.right.equalTo(titleLabel.right);
            make.size.equalTo(CGSizeMake(150, 14));
        }];
    }
    return self;
}

/**
 *  设置子控件的数据
 */
- (void)setTg:(XMGTg *)tg
{
    _tg = tg;
    self.iconImageView.image = [UIImage imageNamed:tg.icon];
    self.titleLabel.text = tg.title;
    self.priceLabel.text = [NSString stringWithFormat:@"¥%@",tg.price];
    self.buyCountLabel.text = [NSString stringWithFormat:@"%@人已购买",tg.buyCount];
}
@end
注意:使用Masonry进行约束

3.控制器代码如下:
//  ViewController.h

#import 

@interface ViewController : UITableViewController

@end
//  ViewController.m

#import "ViewController.h"
#import "XMGTgCell.h"
#import "XMGTg.h"
#import "MJExtension.h"

@interface ViewController ()

/** 所有的团购数据 */
@property (nonatomic, strong) NSArray *tgs;
@end

@implementation ViewController

- (NSArray *)tgs
{
    if (!_tgs) {
        
//        NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"tgs.plist" ofType:nil]];
        
//        NSMutableArray *temp = [NSMutableArray array];
//        for (NSDictionary *tgDict in dictArray) {
//            [temp addObject:[XMGTg tgWithDict:tgDict]];
//        }

//        _tgs = [XMGTg mj_objectArrayWithKeyValuesArray:dictArray];
//        _tgs = [XMGTg mj_objectArrayWithFile:[[NSBundle mainBundle] pathForResource:@"tgs.plist" ofType:nil]];
        
        _tgs = [XMGTg mj_objectArrayWithFilename:@"tgs.plist"];
    }
    return _tgs;
}

NSString *ID = @"tg";
- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.tableView.rowHeight = 70;
    
    // 根据ID 注册 对应的cell类型 为XMGTgCell
    [self.tableView registerClass:[XMGTgCell class] forCellReuseIdentifier:ID];
}

#pragma mark - 数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.tgs.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // 访问缓存池
    XMGTgCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
    
    // 设置数据(传递模型)
    cell.tg = self.tgs[indexPath.row];
    
    return cell;
}

@end
注意:使用MJExtension进行数据转模型, 使用 Masonry进行约束

二.使用xib自定义Cell(使用MJExtension和AutoLayout)

1.模型代码不变


2.创建一个继承UITableViewCell的Cell并带xib,在xib中通过Autolayout约束cell,然后连线到XMGTgCell.m里面

cell代码如下:

//  XMGTgCell.h

#import 

@class XMGTg;
@interface XMGTgCell : UITableViewCell

/** 团购模型 */
@property (nonatomic, strong) XMGTg *tg;
@end
//  XMGTgCell.m

#import "XMGTgCell.h"
#import "XMGTg.h"

@interface XMGTgCell ()
@property (weak, nonatomic) IBOutlet UIImageView *iconImageView;
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UILabel *priceLabel;
@property (weak, nonatomic) IBOutlet UILabel *buyCountLabel;

@end
@implementation XMGTgCell

- (void)setTg:(XMGTg *)tg
{
    _tg  = tg;
    self.iconImageView.image = [UIImage imageNamed:tg.icon];
    self.titleLabel.text = tg.title;
    self.priceLabel.text = [NSString stringWithFormat:@"¥%@",tg.price];
    self.buyCountLabel.text = [NSString stringWithFormat:@"%@人已购买",tg.buyCount];
}

@end
3.控制器代码如下:

//  ViewController.h

#import 

@interface ViewController : UITableViewController
@end
//  ViewController.m

#import "ViewController.h"
#import "XMGTg.h"
#import "MJExtension.h"
#import "XMGTgCell.h"

@interface ViewController ()

/** 所有的团购数据 */
@property (nonatomic, strong) NSArray *tgs;
@end

@implementation ViewController

- (NSArray *)tgs
{
    if (!_tgs) {
        _tgs = [XMGTg mj_objectArrayWithFilename:@"tgs.plist"];
    }
    return _tgs;
}

NSString *ID = @"tg";
- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.tableView.rowHeight = 70;

 [self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([XMGTgCell class]) bundle:nil] forCellReuseIdentifier:tgID];
    [self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([XMGTestCell class]) bundle:nil] forCellReuseIdentifier:testID];

}

#pragma mark - 数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.tgs.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row % 2 == 0) {
        // 访问缓存池
        XMGTgCell *cell = [tableView dequeueReusableCellWithIdentifier:tgID];
        // 设置数据(传递模型)
        cell.tg = self.tgs[indexPath.row];
          return cell;
    } else {
        XMGTestCell *cell = [tableView dequeueReusableCellWithIdentifier:testID];
        return cell;
    }
}

@end

注意: [ self . tableView registerNib [ UINib nibWithNibName : NSStringFromClass ([ XMGTgCell class ]) bundle : nil ] forCellReuseIdentifier : ID ]; 注册的时候要从xib中注册cell,如果使用的cell不一样,要分别注册cell并且判断

三.使用storyboard自定义cell

模型的代码和cell的代码和使用xib自定义cell里面的一样,使用storyboard自定义cell的流程为先在storyboard的tableView里面添加一个cell,然后在cell的contentView里面添加控件和约束,cell里面进行的约束就和在xib中的操作一样,最后把cell里面的控件连线带cell.m文件里面.

1.如果自定义的cell不一样,就添加多个cell在tableview里面,之后的操作类似,最后取出cell的时候要判断需要使用哪个cell

2.storyboard里面自定义cell不需要注册cell.因为并没有cell你怎么注册呢

3.然后不要忘记把cell的identify写上,留着复用.

4.记得要把tableViewCell的类型改成动态单元格


代码如下:

//  ViewController.m

#import "ViewController.h"
#import "XMGTg.h"
#import "MJExtension.h"
#import "XMGTgCell.h"

@interface ViewController ()

/** 所有的团购数据 */
@property (nonatomic, strong) NSArray *tgs;
@end

@implementation ViewController

- (NSArray *)tgs
{
    if (!_tgs) {
        _tgs = [XMGTg mj_objectArrayWithFilename:@"tgs.plist"];
    }
    return _tgs;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableView.rowHeight = 70;
}

#pragma mark - 数据源方法
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.tgs.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row % 2 == 0) {
        static NSString *ID = @"tg";
        // 访问缓存池
        XMGTgCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
        
        // 设置数据(传递模型)
        cell.tg = self.tgs[indexPath.row];
        return cell;
    } else {
        return [tableView dequeueReusableCellWithIdentifier:@"test"];
    }
}
@end


补充:

   1、通过xib自定义cell,获取cell时若无可重用cell,将创建新的cell并调用其中的awakeFromNib方法,可通过重写这个方法添加更多页面内容

    2、通过代码自定义cell,获取cell时若无可重用cell,将调用cell中的initWithStyle:withReuseableCellIdentifier:方法创建新的cell

    1.自定义cell时,注册的方法

    若使用nib,使用 registerNib:注册,dequeue时会调用 cell -(void)awakeFromNib 

    不使用nib,使用 registerClass:注册, dequeue时会调用 cell - (id)initWithStyle:withReuseableCellIdentifier:



你可能感兴趣的:(UI进阶)