UITableViewCell总结

// 注意:
1. 通过xib来创建UITableViewCell需要在xib的identity上写上重用标识

 2. 通过storyboard来创建UITableViewCell需要在storyboard的identity上写上重用标识

 3.  有时候每一行的cell用的不一定是同一种UITableVIewCell,对象池中也会有不同的UITableViewCell等待重用,那么在重用的时候可能得到的是错误的UITableViewCell}
     解决方法:可以通过重用属性reuseIdentifier来对应不同的UITableViewCell

 4. 往cell添加子控件的时候,把子控件添加到contentView上面

 5. 不应该在initWithStyle中设置子控件的Frame,因为父控件的Frame还没有确定,子控件设置Frame不太好,我们应该在layoutSubviews中设置Frame
 layoutSubviews (一定要调用父类) :
    当一个控件的frame发生改变的时候调用,Frame前后要不一致
    将一个控件添加到当前控件的时候调用

一、UITableViewCell重用的封装

+ (instancetype)HeroCell:(UITableView *)tableView;{
    HeroTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ID"];
    if (!cell) {
        cell = [[HeroTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"ID"];
    }
    return cell;
}

二、UITableViewCell的封装 - 系统自定义

#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的封装 - 动态单元格
1.动态单元格得使用UITableViewController

2.UITableViewController的动态单元格cell要写自定义的UITableViewCell,从而通过UITableViewCell实现自定义

3.UITableViewCell -> AppViewCell的代码实现

#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;
    /// 设置已下载
    self.app.isDownloaded = YES;
    /// 判断代理是否实现了代理方法
    if ([self.delegate respondsToSelector:@selector(downloadBtnDidClick:)]) {
        [self.delegate downloadBtnDidClick:self];
    }
}

+ (instancetype)appViewCell:(UITableView *)tableView{
    //dequeueReusableCellWithIdentifier会从缓存中创建Cell,但是如果缓存中没有可重用的cell,则查询系统的cell原型,通过原型创建cell,.没有原型则报错:
    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,下载数量:%@",app.size,app.download];
    self.downloadBtn.enabled = !app.isDownloaded;
}
@end

四、UITableViewCell的封装 - xib
1.xib名和UITableViewCell名一般相同
2.xib中的控件要进行属性连线
3.代码实现

#import <UIKit/UIKit.h>
@class CZTg;

@interface CZTgCell : UITableViewCell
//返回当前自定义的cell
+ (instancetype) tgCell:(UITableView *)tableView;
//为当前自定义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

//创建自定义cell
+ (instancetype)tgCell:(UITableView *)tableView
{
    //1.定义重用标识
    NSString *ID=@"tg";
    //2.从缓存中创建cell
    CZTgCell *cell=[tableView dequeueReusableCellWithIdentifier:ID];
    //3.判断是否成功创建出cell,如果没有就自己从Xib中创建
    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中,再设置控件的属性值
1.2在-(void)setMessageFrame方法中设置数据
1.3在-(void)layoutSubviews中设置Frame (layoutSubviews是在子控件添加到父类的时候会调用)
2.控件的Frame已经在模型中实现了,所以cell就不需要再设置Frame
3.代码的实现:

#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) {
        //这个方法是父类的方法,也就意味着它只能创建出父类中默认的系统自带的cell.而不能满足我们的需要,所以我们就需要做重写,在调用方法的时候调用我们子类自己重写过后的方法。
        cell=[[CZMessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID];
    }
    return  cell;
}
//根据多态,系统会根据类型调用子类重写过后的方法
- (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;
        //设置居中
        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;
        //设置按钮的文本色
        [textView setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
        //设置按钮的字体大小
        textView.titleLabel.font=[UIFont systemFontOfSize:14];
        //设置自动换行
        textView.titleLabel.numberOfLines=0;
        //为按钮添加内容的内间距
        textView.contentEdgeInsets=UIEdgeInsetsMake(0, 20, 0, 20);
        //为按钮添加背景色
        //textView.backgroundColor=[UIColor redColor];
        [self addSubview:textView];
    }
    return self;
}

- (void)setMessageFrame:(CZMessageCellFrame *)messageFrame
{
    _messageFrame=messageFrame;
    //设置数据
    [self setDatas];
}
//设置数据
- (void) setDatas
{
    CZMessage *msg=self.messageFrame.message;

    self.timeView.text=msg.time;

    if (msg.type==MessageTypeMe) {
        self.iconView.image=[UIImage imageNamed:@"me"];
        //根据消息类型设置消息文本的背景图片
        [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];
}

//当将当前控件添加到父容器的时候,自动调用这个方法,设置它的子控件的Frame
//如现在这个情况:当创建好cell,添加到tableView中的时候,会调用这个方法设置cell 的三个子控件的frame
- (void) layoutSubviews
{
    //判断是否需要显示时间
    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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 227,401评论 6 531
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 98,011评论 3 413
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 175,263评论 0 373
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 62,543评论 1 307
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 71,323评论 6 404
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,874评论 1 321
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,968评论 3 439
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 42,095评论 0 286
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 48,605评论 1 331
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 40,551评论 3 354
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,720评论 1 369
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,242评论 5 355
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,961评论 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,358评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 35,612评论 1 280
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 51,330评论 3 390
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,690评论 2 370

推荐阅读更多精彩内容

  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 12,142评论 4 61
  • UITableViewCell 父类是UIView UITableView的每一行都是一个UITableViewC...
    翻这个墙阅读 6,635评论 0 1
  • 1.属性readwrite,readonly,assign,retain,copy,nonatomic 各是什么作...
    曾令伟阅读 1,075评论 0 10
  • 一大早朋友打电话送来几张票:“今晚七点,来看我们县的春晚!” 尽管不是演员,到现场的那一刻也是无比激动的:绚丽的舞...
    时光呵阅读 152评论 0 0
  • 半夜 生物钟把我闹醒 床头迷笼的光 黑夜里充盈的瞳眸 母亲这疲累卑小的身份 时常骄傲里填满丧气 时常心安里浇灌惶恐...
    半壁残月阅读 328评论 2 4