UITableView等高Cell的实例

需要做一个如下效果的实例,每个Cell都是相同的内容,布局以及高度

新建一个iOS Single App工程

将ViewController继承改为UITableViewController

将storyboard中的ViewController控件删除,放置一个TabelViewController控件,将其类名设置为ViewController,并设置为初始View

以下是数据的plist文件

根据plist的数据结构创建数据模型:

ZFDataMode.h

#import <Foundation/Foundation.h>

@interface ZFDataMode : NSObject

@property(strong,nonatomic)NSString *icon;
@property(strong,nonatomic)NSString *title;
@property(strong,nonatomic)NSString *price;
@property(strong,nonatomic)NSString *buyCount;

+ (instancetype)dataWithDict:(NSDictionary*)dict;

@end

ZFDataMode.m

#import "ZFDataMode.h"

@implementation ZFDataMode

+ (instancetype)dataWithDict:(NSDictionary*)dict
{
    ZFDataMode *data = [[ZFDataMode alloc] init];
    data.icon = dict[@"icon"];
    data.title = dict[@"title"];
    data.price = dict[@"price"];
    data.buyCount = dict[@"buyCount"];
    return data;
}

@end

根据概念图创建自定义Cell

布局方式一:布局方式采用Frame设置,因此布局设置必须在layoutSubviews方法中进行

ZFTableViewCell.h

#import <UIKit/UIKit.h>

@class ZFDataMode;

@interface ZFTableViewCell : UITableViewCell

- (instancetype)initWithFrame:(CGRect)frame;
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier;
- (void)layoutSubviews;

- (void)configWithModel:(ZFDataMode*) model;

@end

ZFTableViewCell.m

#import "ZFTableViewCell.h"
#import "ZFDataMode.h"

@interface ZFTableViewCell()

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

@end

@implementation ZFTableViewCell

- (instancetype)initWithFrame:(CGRect)frame
{
    if(self = [super initWithFrame:frame])
    {
        NSLog(@"initWithFrame");
    }
    return self;
}

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if(self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])
    {
        UIImageView *iconImageView = [[UIImageView alloc]init];
        [self.contentView addSubview:iconImageView];
        self.iconImageView = iconImageView;

        UILabel *titleLabel = [[UILabel alloc]init];
        [self.contentView addSubview:titleLabel];
        self.titleLabel = titleLabel;
        self.titleLabel.font = [UIFont systemFontOfSize:18];

        UILabel *priceLabel = [[UILabel alloc]init];
        [self.contentView addSubview:priceLabel];
        self.priceLabel = priceLabel;
        self.priceLabel.font = [UIFont systemFontOfSize:18];
        self.priceLabel.textColor = [UIColor orangeColor];

        UILabel *buyCountLabel = [[UILabel alloc]init];
        [self.contentView addSubview:buyCountLabel];
        self.buyCountLabel = buyCountLabel;
        self.buyCountLabel.font = [UIFont systemFontOfSize:14];
        self.buyCountLabel.textAlignment = NSTextAlignmentRight;
        self.buyCountLabel.textColor = [UIColor lightGrayColor];
    }
    return self;
}

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

- (void)layoutSubviews
{
    [super layoutSubviews];
    CGFloat space = 10;

    CGFloat iconImageX = space;
    CGFloat iconImageY = space;
    CGFloat iconImageW = 80;
    CGFloat iconImageH = self.contentView.frame.size.height - 2 * space;
    self.iconImageView.frame = CGRectMake(iconImageX, iconImageY, iconImageW, iconImageH);

    CGFloat titleLabelX = iconImageX + iconImageW + 10;
    CGFloat titleLabelY = iconImageY;
    CGFloat titleLabelW = self.contentView.frame.size.width - titleLabelX - space;
    CGFloat titleLabelH = 20;
    self.titleLabel.frame = CGRectMake(titleLabelX, titleLabelY, titleLabelW, titleLabelH);

    CGFloat priceLabelW = 100;
    CGFloat priceLabelH = 20;
    CGFloat priceLabelX = titleLabelX;
    CGFloat priceLabelY = iconImageX + iconImageH - priceLabelH;
    self.priceLabel.frame = CGRectMake(priceLabelX, priceLabelY, priceLabelW, priceLabelH);

    CGFloat buyCountLabelW = 150;
    CGFloat buyCountLabelH = 14;
    CGFloat buyCountLabelX = titleLabelX + titleLabelW - buyCountLabelW;
    CGFloat buyCountLabelY = iconImageY + iconImageH - buyCountLabelH;
    self.buyCountLabel.frame = CGRectMake(buyCountLabelX, buyCountLabelY, buyCountLabelW, buyCountLabelH);
}

@end

ViewController.m

#import "ViewController.h"
#import "ZFTableViewCell.h"
#import "ZFDataMode.h"

@interface ViewController ()

@property(strong, nonatomic)NSArray<ZFDataMode*> *tableDatas;

@end

@implementation ViewController

NSString *cellId = @"cell";

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (BOOL)prefersStatusBarHidden
{
    return YES;
}

- (NSArray *)tableDatas
{
    if(_tableDatas == nil)
    {
        NSMutableArray *datas = [NSMutableArray array];
        NSArray<NSDictionary*> *tempArr = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"tgs" ofType:@"plist"]];
        NSLog(@"%@",tempArr);
        for(NSDictionary *dict in tempArr)
        {
            ZFDataMode *dataMode = [ZFDataMode dataWithDict:dict];
            [datas addObject:dataMode];
        }
        _tableDatas = datas;
    }
    return _tableDatas;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.tableDatas.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ZFTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];

    if(cell == nil)
    {
        cell = [[ZFTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
        [cell configWithModel:self.tableDatas[indexPath.row]];
    }

    return cell;
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 70;
}

@end

关于自定义cell也可以用注册cell类的方式

ViewController.m 修改

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.tableView registerClass:[ZFTableViewCell class] forCellReuseIdentifier:cellId];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ZFTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];

    //这里无需if(cell == nil)判断
    cell = [[ZFTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
        [cell configWithModel:self.tableDatas[indexPath.row]];

    return cell;
}

布局方式二,采用AutoLayout布局,使用Mesonry框架实现

ZFTableViewCell.m修改

//头部设置如下宏和头文件
//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"

//AutoLayout布局无需在layoutSubviews中再设置,而是在控件的父级View一经决定就可以设置,因此修改如下部分
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    if(self = [super initWithStyle:style reuseIdentifier:reuseIdentifier])
    {
        CGFloat space = 10;

        UIImageView *iconImageView = [[UIImageView alloc]init];
        [self.contentView addSubview:iconImageView];
        self.iconImageView = iconImageView;

        [iconImageView makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(self.contentView).offset(space);
            make.left.equalTo(self.contentView).offset(space);
            make.bottom.equalTo(self.contentView).offset(-space);
            make.width.equalTo(80);
        }];

        UILabel *titleLabel = [[UILabel alloc]init];
        [self.contentView addSubview:titleLabel];
        self.titleLabel = titleLabel;
        self.titleLabel.font = [UIFont systemFontOfSize:18];

        [titleLabel makeConstraints:^(MASConstraintMaker *make) {
            make.top.equalTo(iconImageView.top).offset(0);
            make.left.equalTo(iconImageView.right).offset(space);
            make.height.equalTo(20);
            make.right.equalTo(self.contentView).offset(space);
        }];

        UILabel *priceLabel = [[UILabel alloc]init];
        [self.contentView addSubview:priceLabel];
        self.priceLabel = priceLabel;
        self.priceLabel.font = [UIFont systemFontOfSize:18];
        self.priceLabel.textColor = [UIColor orangeColor];

        [priceLabel makeConstraints:^(MASConstraintMaker *make) {
            make.bottom.equalTo(self.contentView).offset(-space);
            make.left.equalTo(iconImageView.right).offset(space);
            make.width.equalTo(100);
            make.height.equalTo(20);
        }];

        UILabel *buyCountLabel = [[UILabel alloc]init];
        [self.contentView addSubview:buyCountLabel];
        self.buyCountLabel = buyCountLabel;
        self.buyCountLabel.font = [UIFont systemFontOfSize:14];
        self.buyCountLabel.textAlignment = NSTextAlignmentRight;
        self.buyCountLabel.textColor = [UIColor lightGrayColor];

        [buyCountLabel makeConstraints:^(MASConstraintMaker *make) {
            make.right.equalTo(self.contentView).offset(-space);
            make.bottom.equalTo(priceLabel.bottom).offset(0);
            make.width.equalTo(150);
            make.height.equalTo(14);
        }];
    }
    return self;
}

方式三:采用XIB方式定义Cell,AutoLayout实现

根据概念图在XIB中搭建模型,根控件是UITableViewCell

然后做好AutoLayout布局

ViewController.m 修改

- (void)viewDidLoad {
    [super viewDidLoad];

    [self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([ZFTableViewCell class]) bundle:nil] forCellReuseIdentifier:cellId];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    ZFTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];

    //无需cell = [[ZFTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellId];
    [cell configWithModel:self.tableDatas[indexPath.row]];

    return cell;
}

方式四:storyboard自定义控件,AutoLayout布局

在storyboard TableView控件中拖入一个TableViewCell,按照概念图布局控件

ViewController.m 修改

- (void)viewDidLoad {
    [super viewDidLoad];

    self.tableView.rowHeight = 70;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellId = @"cell";
    // 访问缓存池
    XMGTgCell *cell = [tableView dequeueReusableCellWithIdentifier:cellId];

    [cell configWithModel:self.tableDatas[indexPath.row]];

    return cell;

}

使用MJExtension将数据转模型

ViewController.m 修改

- (NSArray *)tableDatas
{
    if (!_tableDatas) {

        //读取的plist文件只限于mainBundle
        _tableDatas = [ZFDataMode mj_objectArrayWithFilename:@"tgs.plist"];

        /**
        也可以是
        NSMutableArray *datas = [NSMutableArray array];
        _tgs = [ZFDataMode mj_objectArrayWithKeyValuesArray:datas];
        */
    }
    return _tgs;
}
/** 即可代替如下代码
- (NSArray *)tableDatas
{
    if(_tableDatas == nil)
    {
        NSMutableArray *datas = [NSMutableArray array];

        NSArray<NSDictionary*> *tempArr = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"tgs" ofType:@"plist"]];
        NSLog(@"%@",tempArr);
        for(NSDictionary *dict in tempArr)
        {
            ZFDataMode *dataMode = [ZFDataMode dataWithDict:dict];
            [datas addObject:dataMode];
        }
        _tableDatas = datas;
    }
    return _tableDatas;
}
*/

results matching ""

    No results matching ""