TableView使用
1.tableView如何顯示數(shù)據(jù)
- 設(shè)置dataSource數(shù)據(jù)源方法
- 數(shù)據(jù)源要遵守UITableViewDataSource協(xié)議
- 數(shù)據(jù)源要實(shí)現(xiàn)協(xié)議中的某些方法
1.告訴tableView第Section組有多少行
-(NSInterger)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath
2.告訴tableView第indexPath行顯示怎樣的cell
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexpath
3.告訴TableView第section組頭部標(biāo)題
-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
4.告訴tableView第section組的尾部標(biāo)題
-(NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section
UITableView的常見(jiàn)設(shè)置
//1.分割線顏色
self.tableView.separetorColor = [UIColor redColor];
//2.隱藏分割線
self.tableView.separatorStyle = [UITableViewCellSeparatorStyleNone];
//3.取消選中樣式
cell.selectionStyle = UITableViewCellSelectionStyleNone;
//4.設(shè)置選中的背景色
UIView *selectedBackgroundView = [[UIView alloc] init];
selectedBackgroundView.backgroundColor = [UIColor redColor];
cell.selectedBackgroundView = selectedBackgroundView;
//5.設(shè)置默認(rèn)的背景色
cell.backgroundColor = [UIColor blueColor];
//6.設(shè)置默認(rèn)的背景色
UIView *backgroundView = [[UIView alloc] init];
backgroundView.backgroundColor = [UIcolor greenColor];
cell.backgroundView = backgroundView;
//7.設(shè)置指示器
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.accessoryView = [[UISwitch alloc] init];
cell的循環(huán)利用
1.什么時(shí)候調(diào)用cell呢舶吗?
每當(dāng)有一個(gè)cell進(jìn)入視野范圍內(nèi)就會(huì)調(diào)用
1.循環(huán)利用方式1
/**
* 什么時(shí)候調(diào)用:每當(dāng)有一個(gè)cell進(jìn)入視野范圍內(nèi)就會(huì)調(diào)用
*/
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
// 0.重用標(biāo)識(shí)
// 被static修飾的局部變量:只會(huì)初始化一次尿孔,在整個(gè)程序運(yùn)行過(guò)程中否纬,只有一份內(nèi)存
static NSString *ID = @"cell";
// 1.先根據(jù)cell的標(biāo)識(shí)去緩存池中查找可循環(huán)利用的cell
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
// 2.如果cell為nil(緩存池找不到對(duì)應(yīng)的cell)
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
// 3.覆蓋數(shù)據(jù)
cell.textLabel.text = [NSString stringWithFormat:@"testdata - %zd", indexPath.row];
return cell;
}
2.循環(huán)利用方式2
(1)定義一個(gè)全局變量
//定義重用標(biāo)識(shí)
NSString *ID = @"cell";
(2)注冊(cè)某個(gè)標(biāo)識(shí)對(duì)應(yīng)的cell類型
//在viewDidLoad中注冊(cè)cell
- (void)viewDidLoad {
[super viewDidLoad];
// 注冊(cè)某個(gè)標(biāo)識(shí)對(duì)應(yīng)的cell類型
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:ID];
}
(3)在數(shù)據(jù)源方法中返回cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//1.去緩存池中查找cell
UITabelViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
//2.覆蓋數(shù)據(jù)
cell.textLabel.text = [NSString stringWithFormat:@"testdata - %zd",indexPath.row];
return cell;
自定義cell
xib自定義等高cell
- 1.創(chuàng)建一個(gè)繼承自UITableViewCell的子類蛋欣,比如DealCell
- 2.創(chuàng)建一個(gè)xib文件(文件名建議和cell的類名一樣丐巫,比如DealCell.xib)
- 拖拽一個(gè)UITableViewCell出來(lái)
- 修改cell的class為DealCell
- 設(shè)置cell的重用標(biāo)識(shí)
- 往cell中添加需要用到的子控件 - 3.在控制器中
- 利用registerNib....方法中注冊(cè)xib文件
- 利用重用標(biāo)識(shí)找到cell(如果沒(méi)有注冊(cè)xib文件锨侯,就需要手動(dòng)去加載xib文件)
- 給cell傳遞模型數(shù)據(jù)
- 4.在DealCell中
- 將xib中的子控件連線到類拓展中 即DealCell.m文件中
- 需要提供一個(gè)模型屬性饺谬,重寫模型的set方法捂刺,在這個(gè)方法中設(shè)置模型數(shù)據(jù)到子控件上
- 也可以將創(chuàng)建獲得cell的代碼封裝起來(lái)
重寫set方法 設(shè)置數(shù)據(jù)
- (void)setDeal:(XMGDeal *)deal
{
_deal = deal;
// 設(shè)置數(shù)據(jù)
self.iconView.image = [UIImage imageNamed:deal.icon];
self.titleLabel.text = deal.title;
self.priceLabel.text = [NSString stringWithFormat:@"¥%@", deal.price];
self.buyCountLabel.text = [NSString stringWithFormat:@"%@人已購(gòu)買", deal.buyCount];
}
模型比如如下代碼:
Status.h
@interface XMGStatus : NSObject
@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSString *text;
@property (strong, nonatomic) NSString *icon;
@property (strong, nonatomic) NSString *picture;
@property (assign, nonatomic, getter=isVip) BOOL vip;
+ (instancetype)statusWithDict:(NSDictionary *)dict;
@end
Status.m
@implementation XMGStatus
+ (instancetype)statusWithDict:(NSDictionary *)dict
{
XMGStatus *status = [[self alloc] init];
[status setValuesForKeysWithDictionary:dict];
return status;
}
@end
代碼自定義cell(frame)
- 1.創(chuàng)建一個(gè)繼承自UITableViewCell的子類,比如DealCell
- 在initWithStyle:reuseIdentifier:方法中
- 添加子控件
- 設(shè)置子控件的初始化屬性(比如文字顏色募寨、字體)
- 2.在控制器中
- 利用registerClass...方法注冊(cè)DealCell類
- 利用重用標(biāo)識(shí)找到cell(如果沒(méi)有注冊(cè)類族展,就需要手動(dòng)創(chuàng)建cell)
- 給cell傳遞模型數(shù)據(jù)
- 也可以將創(chuàng)建獲得的cell的代碼封裝起來(lái)
在initWithStyle:reuseIdentifier方法中添加子控件
// 1.在initWithStyle:reuseIdentifier:方法中添加子控件
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
UIImageView *iconView = [[UIImageView alloc] init];
[self.contentView addSubview:iconView];
self.iconView = iconView;
UILabel *titleLabel = [[UILabel alloc] init];
[self.contentView addSubview:titleLabel];
self.titleLabel = titleLabel;
UILabel *priceLabel = [[UILabel alloc] init];
priceLabel.textColor = [UIColor orangeColor];
[self.contentView addSubview:priceLabel];
self.priceLabel = priceLabel;
UILabel *buyCountLabel = [[UILabel alloc] init];
buyCountLabel.textAlignment = NSTextAlignmentRight;
buyCountLabel.font = [UIFont systemFontOfSize:14];
buyCountLabel.textColor = [UIColor lightGrayColor];
[self.contentView addSubview:buyCountLabel];
self.buyCountLabel = buyCountLabel;
}
return self;
}
fram代碼如下:
// 2.在layoutSubviews方法中設(shè)置子控件的frame
- (void)layoutSubviews
{
[super layoutSubviews];
CGFloat contentH = self.contentView.frame.size.height;
CGFloat contentW = self.contentView.frame.size.width;
CGFloat margin = 10;
CGFloat iconX = margin;
CGFloat iconY = margin;
CGFloat iconW = 100;
CGFloat iconH = contentH - 2 * iconY;
self.iconView.frame = CGRectMake(iconX, iconY, iconW, iconH);
// titleLabel
CGFloat titleX = CGRectGetMaxX(self.iconView.frame) + margin;
CGFloat titleY = iconY;
CGFloat titleW = contentW - titleX - margin;
CGFloat titleH = 21;
self.titleLabel.frame = CGRectMake(titleX, titleY, titleW, titleH);
// CGRectMake(titleX, titleY?, titleW, titleH);
// priceLabel
CGFloat priceX = titleX;
CGFloat priceH = 21;
CGFloat priceY = contentH - margin - priceH;
CGFloat priceW = 70;
self.priceLabel.frame = CGRectMake(priceX, priceY, priceW, priceH);
// buyCountLabel
CGFloat buyCountH = priceH;
CGFloat buyCountY = priceY;
CGFloat buyCountX = CGRectGetMaxX(self.priceLabel.frame) + margin;
CGFloat buyCountW = contentW - buyCountX - margin;
self.buyCountLabel.frame = CGRectMake(buyCountX, buyCountY, buyCountW, buyCountH);
}
代碼自定義cell(autolayout)
- 1.創(chuàng)建一個(gè)繼承自UITableViewCell的子類,比如XMGDealCell
- 在initWithStyle:reuseIdentifier:方法中
- 添加子控件
- 添加子控件的約束(建議使用
Masonry
) - 設(shè)置子控件的初始化屬性(比如文字顏色绪商、字體)
- 需要提供一個(gè)模型屬性苛谷,重寫模型的set方法,在這個(gè)方法中設(shè)置模型數(shù)據(jù)到子控件
- 2.在控制器中
- 利用registerClass...方法注冊(cè)XMGDealCell類
- 利用重用標(biāo)識(shí)找到cell(如果沒(méi)有注冊(cè)類格郁,就需要手動(dòng)創(chuàng)建cell)
- 給cell傳遞模型數(shù)據(jù)
- 也可以將創(chuàng)建獲得cell的代碼封裝起來(lái)(比如cellWithTableView:方法)
autolayout代碼如下
- (void)viewDidLoad {
[super viewDidLoad];
[self performSelector:@selector(test1) withObject:self afterDelay:5];//5秒后執(zhí)行test1
//藍(lán)色控件
UIView *blueView = [[UIView alloc] init];
blueView.backgroundColor = [UIColor blueColor];
[self.view addSubview:blueView];
//紅色控件
UIView *redView = [[UIView alloc] init];
redView.backgroundColor = [UIColor redColor];
[self.view addSubview:redView];
//添加約束
CGFloat margin = 20;
CGFloat height = 50;
//藍(lán)色控件的約束
[blueView makeConstraints:^(MASConstraintMaker *make){
make.left.equalTo(self.view.left).offset(margin);//左邊與父控件間距20
make.right.equalTo(redView.left).offset(-margin);//右邊與紅色控件間距20
make.bottom.equalTo(self.view.bottom).offset(-margin);//底部與父控件的底部間距20
make.height.equalTo(height);//
make.top.equalTo(redView.top);
make.bottom.equalTo(redView.bottom);
make.width.equalTo(redView.width);
}];
//紅色控件的約束
[redView makeConstraints:^(MASConstraintMaker *make) {
make.right.equalTo(self.view.right).offset(-margin);
}];
}
8沟睢!非等高的cell
xib自定義(重點(diǎn))
- 1.創(chuàng)建一個(gè)繼承自UITableViewCell的子類例书,比如XMGDealCell
- 2.創(chuàng)建一個(gè)xib文件(文件名建議跟cell的類名一樣)锣尉,比如StatusCell.xib
- 拖拽一個(gè)UITableViewCell出來(lái)
- 修改cell的class為StatusCell
- 設(shè)置cell的重用標(biāo)識(shí)
- 往cell中添加需要用到的子控件
- 3.在控制器中
- 利用registerNib...方法注冊(cè)xib文件
- 利用重用標(biāo)識(shí)找到cell(如果沒(méi)有注冊(cè)xib文件,就需要手動(dòng)去加載xib文件)
- 給cell傳遞模型數(shù)據(jù)
- 4.在XMGDealCell中
- 將xib中的子控件連線到類擴(kuò)展中
- 需要提供一個(gè)模型屬性决采,重寫模型的set方法自沧,在這個(gè)方法中設(shè)置模型數(shù)據(jù)到子控件上
- 也可以將創(chuàng)建獲得cell的代碼封裝起來(lái)(比如cellWithTableView:方法) - 在模型中增加一個(gè)cellHeight屬性,用來(lái)存放對(duì)應(yīng)cell的高度
- 在cell的模型屬性set方法中調(diào)用[self layoutIfNeed]方法強(qiáng)制布局树瞭,然后計(jì)算出模型的cellheight屬性值
- 在控制器中實(shí)現(xiàn)tableView:estimatedHeightForRowAtIndexPath:方法拇厢,返回一個(gè)估計(jì)高度,比如200
- 在控制器中實(shí)現(xiàn)tableView:heightForRowAtIndexPath:方法晒喷,返回cell的真實(shí)高度(模型中的cellHeight屬性)
示例模型代碼如下
status.h
//微博模型
@interface Status_M : NSObject
@property (nonatomic,strong) NSSet *name;
@property (nonatomic,strong) NSSet *text;
@property (nonatomic,strong) NSString *icon;
@property (nonatomic,strong) NSString *picture;
@property (assign, nonatomic, getter=isVip) BOOL vip;
//cell的高度
@property (assign, nonatomic) CGFloat cellHeight;
+(instancetype)statusWithDict:(NSDictionary *)dict
status.m
@implementation Status_M
+(instancetype)statusWithDict:(NSDictionary *)dict
{
Status_M *status = [[self alloc] init];
[status setValuesForKeysWithDictionary:dict];
return status;
}
@end
自定義cell封裝代碼如下
StatusCell.h
#import <UIKit/UIKit.h>
@class Status_M;
@interface StatusCell : UITableViewCell
+(instancetype)cellWithTableView:(UITableView *)tableView;
//微博模型數(shù)據(jù)
@property (nonatomic, strong) Status_M *status;
@end
StatusCell.m
#import "StatusCell.h"
#import "Status_M.h"
@interface StatusCell()
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *nameLabel;
@property (weak, nonatomic) IBOutlet UIImageView *vipView;
@property (weak, nonatomic) IBOutlet UILabel *contentLabel;
@property (weak, nonatomic) IBOutlet UIImageView *pictureView;
@end
@implementation StatusCell
+(instancetype)cellWithTableView:(UITableView *)tableView
{
static NSString *ID = @"status";
StatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];
if (cell == nil) {
cell = [[[NSBundle mainBundle] loadNibNamed:NSStringFromClass(self) owner:nil options:nil] lastObject];
}
return cell;
}
//設(shè)置label每行文字的最大寬度:為了保證計(jì)算出來(lái)的數(shù)值跟 真正顯示出來(lái)的 效果一致
-(void)awakeFromNib
{
self.contentLabel.preferredMaxLayoutWidth = [UIScreen mainScreen].bounds.size.width - 20;
}
-(void)setStatus:(Status_M *)status
{
_status = status;
//判斷是否是會(huì)員
if (status.isVip) {
self.nameLabel.textColor = [UIColor orangeColor];
self.vipView.hidden = NO;
}else{
self.nameLabel.textColor = [UIColor blackColor];
self.vipView.hidden = YES;
}
self.nameLabel.text = status.name;
self.iconView.image = [UIImage imageNamed:status.icon];
if (status.picture) {
self.pictureView.hidden = NO;
self.pictureView.image = [UIImage imageNamed:status.picture];
}else{
self.pictureView.hidden = YES;
}
self.contentLabel.text = status.text;
//強(qiáng)制布局
[self layoutIfNeeded];
//計(jì)算cell的高度
if (self.pictureView.hidden) {//沒(méi)有配圖
status.cellHeight = CGRectGetMaxY(self.contentLabel.frame) + 10;
}else{//配圖
status.cellHeight = CGRectGetMaxY(self.pictureView.frame) + 10;
}
}
@end
設(shè)置cellheight
@interface StatusesViewController()
@property (strong, nonatomic) NSArray *statuses;
@end
@implementation StatusesViewController
-(NSArray *)statuses
{
if (_statuses == nil) {
//加載plist中的字典數(shù)組
NSString *path = [[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil];
NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];
//字典數(shù)組-->模型數(shù)組
NSMutableArray *statusArray = [NSMutableArray array];
for (NSDictionary *dict in dictArray) {
Status_M *status = [Status_M statusWithDict: dict];
[statusArray addObject:status];
}
_statuses = statusArray;
}
return _statuses;
}
-(void)viewDidLoad
{
[super viewDidLoad];
}
#pragma mark data source
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.statuses.count;
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
StatusCell *cell = [StatusCell cellWithTableView:tableView];
cell.status = self.statuses[indexPath.row];
return cell;
}
/**
* 返回每一行的高度
*/
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
Status_M *status = self.statuses[indexPath.row];
return status.cellHeight;
}
/**
* 返回每一行的估計(jì)高度
只要返回了估計(jì)高度孝偎,那么就會(huì)先條用tableView:cellForRowAtIndexPath:方法創(chuàng)建cell,再調(diào)用tableView heightForRowAtIndexPath:方法獲取測(cè)cell的真實(shí)高度
*
*/
-(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(nonnull NSIndexPath *)indexPath
{
return 200;
}
@end