// 注意:
1. 通過xib來創(chuàng)建UITableViewCell需要在xib的identity上寫上重用標(biāo)識
2. 通過storyboard來創(chuàng)建UITableViewCell需要在storyboard的identity上寫上重用標(biāo)識
3. 有時(shí)候每一行的cell用的不一定是同一種UITableVIewCell柱查,對象池中也會有不同的UITableViewCell等待重用讨惩,那么在重用的時(shí)候可能得到的是錯(cuò)誤的UITableViewCell}
解決方法:可以通過重用屬性reuseIdentifier來對應(yīng)不同的UITableViewCell
4. 往cell添加子控件的時(shí)候苛茂,把子控件添加到contentView上面
5. 不應(yīng)該在initWithStyle中設(shè)置子控件的Frame,因?yàn)楦缚丶腇rame還沒有確定痊夭,子控件設(shè)置Frame不太好渐逃,我們應(yīng)該在layoutSubviews中設(shè)置Frame
layoutSubviews (一定要調(diào)用父類) :
當(dāng)一個(gè)控件的frame發(fā)生改變的時(shí)候調(diào)用,Frame前后要不一致
將一個(gè)控件添加到當(dāng)前控件的時(shí)候調(diào)用
一液走、UITableViewCell重用的封裝
+ (instancetype)HeroCell:(UITableView *)tableView;{
HeroTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ID"];
if (!cell) {
cell = [[HeroTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"ID"];
}
return cell;
}
二纲菌、UITableViewCell的封裝 - 系統(tǒng)自定義
#import <UIKit/UIKit.h>
@class Hero;
@interface HeroTableViewCell : UITableViewCell
+ (instancetype)HeroCell;
@property (nonatomic, strong) Hero *hero;
@end
#import "HeroTableViewCell.h"
#import "Hero.h"
@implementation HeroTableViewCell
+ (instancetype)HeroCell{
HeroTableViewCell *cell = [[HeroTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:nil];
return cell;
}
- (void)setHero:(Hero *)hero{
_hero = hero;
self.imageView.image = [UIImage imageNamed:hero.icon];
self.textLabel.text = hero.name;
self.detailTextLabel.text = hero.intro;
}
@end
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
Hero *hero = self.heros[indexPath.row];
HeroTableViewCell *cell = [HeroTableViewCell HeroCell];
cell.hero = hero;
return cell;
}
三焕议、UITableViewCell的封裝 - 動態(tài)單元格
1.動態(tài)單元格得使用UITableViewController
2.UITableViewController的動態(tài)單元格cell要寫自定義的UITableViewCell宝磨,從而通過UITableViewCell實(shí)現(xiàn)自定義
3.UITableViewCell -> AppViewCell的代碼實(shí)現(xiàn)
#import <UIKit/UIKit.h>
@class App;
@class AppViewCell;
/// 代理
@protocol AppViewCellDelegate <NSObject>
@optional
- (void)downloadBtnDidClick:(AppViewCell *)appViewCell;
@end
@interface AppViewCell : UITableViewCell
+ (instancetype) appViewCell:(UITableView *)tableView;
@property (nonatomic, strong) App *app;
/// 代理屬性
@property (nonatomic, assign) id<AppViewCellDelegate> delegate;
@end
#import "AppViewCell.h"
#import "App.h"
@interface AppViewCell ()
/// 屬性連線
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *nameView;
@property (weak, nonatomic) IBOutlet UILabel *detailView;
@property (weak, nonatomic) IBOutlet UIButton *downloadBtn;
@end
@implementation AppViewCell
- (IBAction)downloadBtnDidClick {
/// 禁用下載按鈕
self.downloadBtn.enabled = NO;
/// 設(shè)置已下載
self.app.isDownloaded = YES;
/// 判斷代理是否實(shí)現(xiàn)了代理方法
if ([self.delegate respondsToSelector:@selector(downloadBtnDidClick:)]) {
[self.delegate downloadBtnDidClick:self];
}
}
+ (instancetype)appViewCell:(UITableView *)tableView{
//dequeueReusableCellWithIdentifier會從緩存中創(chuàng)建Cell,但是如果緩存中沒有可重用的cell,則查詢系統(tǒng)的cell原型,通過原型創(chuàng)建cell,.沒有原型則報(bào)錯(cuò):
AppViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"app"];
return cell;
}
- (void)setApp:(App *)app{
_app = app;
self.iconView.image = [UIImage imageNamed:app.icon];
self.nameView.text = app.name;
self.detailView.text=[NSString stringWithFormat:@"大兄寻病:%@M懊烤,下載數(shù)量:%@",app.size,app.download];
self.downloadBtn.enabled = !app.isDownloaded;
}
@end
四、UITableViewCell的封裝 - xib
1.xib名和UITableViewCell名一般相同
2.xib中的控件要進(jìn)行屬性連線
3.代碼實(shí)現(xiàn)
#import <UIKit/UIKit.h>
@class CZTg;
@interface CZTgCell : UITableViewCell
//返回當(dāng)前自定義的cell
+ (instancetype) tgCell:(UITableView *)tableView;
//為當(dāng)前自定義cell賦值
@property (nonatomic,strong) CZTg *tg;
@end
#import "CZTgCell.h"
#import "CZTg.h"
@interface CZTgCell()
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@property (weak, nonatomic) IBOutlet UILabel *titleView;
@property (weak, nonatomic) IBOutlet UILabel *priceView;
@property (weak, nonatomic) IBOutlet UILabel *buyCountView;
@end
@implementation CZTgCell
//創(chuàng)建自定義cell
+ (instancetype)tgCell:(UITableView *)tableView
{
//1.定義重用標(biāo)識
NSString *ID=@"tg";
//2.從緩存中創(chuàng)建cell
CZTgCell *cell=[tableView dequeueReusableCellWithIdentifier:ID];
//3.判斷是否成功創(chuàng)建出cell,如果沒有就自己從Xib中創(chuàng)建
if (cell==nil) {
NSLog(@"aaaaaaa");
cell=[[[NSBundle mainBundle] loadNibNamed:@"CZTgCell" owner:self options:nil] lastObject];
}
return cell;
}
- (void)setTg:(CZTg *)tg
{
_tg=tg;
self.iconView.image=[UIImage imageNamed:tg.icon];
self.titleView.text=tg.title;
self.priceView.text=[NSString stringWithFormat:@"¥%@",tg.price];
self.buyCountView.text=[NSString stringWithFormat:@"%@人已購買",tg.buyCount];
}
@end
五宽堆、UITableViewCell的封裝 - 純代碼
1.思路:
1.1重寫UITableViewCell的initWithStyle方法(記得先super父類方法)腌紧,在方法中新建控件并添加到cell中,再設(shè)置控件的屬性值
1.2在-(void)setMessageFrame方法中設(shè)置數(shù)據(jù)
1.3在-(void)layoutSubviews中設(shè)置Frame (layoutSubviews是在子控件添加到父類的時(shí)候會調(diào)用)
2.控件的Frame已經(jīng)在模型中實(shí)現(xiàn)了畜隶,所以cell就不需要再設(shè)置Frame
3.代碼的實(shí)現(xiàn):
#import <UIKit/UIKit.h>
@class CZMessageCellFrame;
@interface CZMessageCell : UITableViewCell
+ (instancetype) messageCell:(UITableView *)tableView;
@property (nonatomic,strong) CZMessageCellFrame *messageFrame;
@end
#import "CZMessageCell.h"
#import "CZMessage.h"
#import "CZMessageCellFrame.h"
@interface CZMessageCell ()
@property (nonatomic,weak) UILabel *timeView;
@property (nonatomic,weak) UIImageView *iconView;
@property (nonatomic,weak) UIButton *textView;
@end
@implementation CZMessageCell
+ (instancetype) messageCell:(UITableView *)tableView
{
NSString *ID=@"QQ";
CZMessageCell *cell=[tableView dequeueReusableCellWithIdentifier:ID];
if (cell==nil) {
//這個(gè)方法是父類的方法壁肋,也就意味著它只能創(chuàng)建出父類中默認(rèn)的系統(tǒng)自帶的cell.而不能滿足我們的需要,所以我們就需要做重寫籽慢,在調(diào)用方法的時(shí)候調(diào)用我們子類自己重寫過后的方法浸遗。
cell=[[CZMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
}
return cell;
}
//根據(jù)多態(tài),系統(tǒng)會根據(jù)類型調(diào)用子類重寫過后的方法
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
//1.先初始化父類成員
self=[super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (self) {
//1.添加timeView
UILabel *timeView=[[UILabel alloc] init];
self.timeView=timeView;
//設(shè)置居中
timeView.textAlignment=NSTextAlignmentCenter;
timeView.font=[UIFont systemFontOfSize:13];
timeView.textColor=[UIColor lightGrayColor];
[self addSubview:timeView];
//2.添加iconView
UIImageView *iconView=[[UIImageView alloc] init];
self.iconView=iconView;
[self addSubview:iconView];
//3.添加textView
UIButton *textView=[[UIButton alloc] init];
self.textView=textView;
//設(shè)置按鈕的文本色
[textView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
//設(shè)置按鈕的字體大小
textView.titleLabel.font=[UIFont systemFontOfSize:14];
//設(shè)置自動換行
textView.titleLabel.numberOfLines=0;
//為按鈕添加內(nèi)容的內(nèi)間距
textView.contentEdgeInsets=UIEdgeInsetsMake(0, 20, 0, 20);
//為按鈕添加背景色
//textView.backgroundColor=[UIColor redColor];
[self addSubview:textView];
}
return self;
}
- (void)setMessageFrame:(CZMessageCellFrame *)messageFrame
{
_messageFrame=messageFrame;
//設(shè)置數(shù)據(jù)
[self setDatas];
}
//設(shè)置數(shù)據(jù)
- (void) setDatas
{
CZMessage *msg=self.messageFrame.message;
self.timeView.text=msg.time;
if (msg.type==MessageTypeMe) {
self.iconView.image=[UIImage imageNamed:@"me"];
//根據(jù)消息類型設(shè)置消息文本的背景圖片
[self.textView setBackgroundImage:[self resizeImageWithName:@"chat_send_nor"] forState:UIControlStateNormal];
[self.textView setBackgroundImage:[self resizeImageWithName:@"chat_send_press_pic"] forState:UIControlStateHighlighted];
}
else
{
self.iconView.image=[UIImage imageNamed:@"other"];
[self.textView setBackgroundImage:[self resizeImageWithName:@"chat_recive_nor"] forState:UIControlStateNormal];
[self.textView setBackgroundImage:[self resizeImageWithName:@"chat_recive_press_pic"] forState:UIControlStateHighlighted];
}
[self.textView setTitle:msg.text forState:UIControlStateNormal];
}
//返回拉伸之后的圖片
- (UIImage *) resizeImageWithName:(NSString *)name
{
return [[UIImage imageNamed:name] resizableImageWithCapInsets:UIEdgeInsetsMake(30, 20, 18, 30) resizingMode:UIImageResizingModeStretch];
}
//當(dāng)將當(dāng)前控件添加到父容器的時(shí)候箱亿,自動調(diào)用這個(gè)方法跛锌,設(shè)置它的子控件的Frame
//如現(xiàn)在這個(gè)情況:當(dāng)創(chuàng)建好cell,添加到tableView中的時(shí)候,會調(diào)用這個(gè)方法設(shè)置cell 的三個(gè)子控件的frame
- (void) layoutSubviews
{
//判斷是否需要顯示時(shí)間
self.timeView.hidden=! self.messageFrame.showTime;
self.timeView.frame=self.messageFrame.timeViewF;
self.iconView.frame=self.messageFrame.iconViewF;
self.textView.frame=self.messageFrame.textViewF;
}
@end