iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(一)
2014-11-02 15:22
771 查看
iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(一)
一、storyboard的处理
直接让控制器继承uitableview controller,然后在storyboard中把继承自uiviewcontroller的控制器干掉,重新拖一个tableview controller,和主控制器进行连线。
项目结构和plist文件
二、程序逻辑业务的处理
第一步,把配图和plist中拿到项目中,加载plist数据(非png的图片放到spooding files中)
第二步,字典转模型,完成plist中数据的加载。属性的注意点(number vip是bool类型,本质是整型的)kvc会智能的把nsnumber转换成bool型的。
第三步,懒加载。
第四步,有了数据之后直接实现数据源方法
(1)一共有几组(如果有一组的,那么可以不写,默认为一组)
(2)每组一共有多少行(数组有多少个元素,就有多少组)
(3)展示数据
1)到缓存中取cell
2)没有的话就创建
3)设置数据
4)返回cell
三、代码
视图部分
TXStatusCell.h文件
TXStatusCell.m文件
TXStatus.h文件
TXStatus.m文件
主控制器部分
TXViewControllerh文件
TXViewController.m文件
阶段性展示:
四、补充说明
1对于展示数据部分的补充说明:
设置数据的时候遇到新的问题:uitableviewcell默认只有一个imageview,一个tabletext和一个详细三个子控件可以用,但是这个微博至少有四个。系统提供的cell不能满足需求,那么我们就在系统提供的cell的基础上为它增加一些功能,新建一个类,自定义cell,让它继承自uitableviewcell。
不用系统的,用自己定义的cell,把自定义的cell头文件导入,还是先去缓存中找,如果找不到就创建一个自定义的cell。创建玩自定义cell后,就应该给cell设置数据,按照封装的思想,设置数据的时候,你把数据给我,我自己爱怎么设置就怎么设置。所以把当前的模型取出来,传递给我cell中得一个属性,我自己重写set方法完成赋值。在cell里面应该增加一个属性,用于接收传入的模型。
此时,应该赋值数据,并对系统原有的封装和操作进行分析。在以前创建的系统的cell一创建的时候默认就有三个子控件提供给我们使用。自定义的cell按照实际的需求(需要创建5个子控件),我们也应该以创建出一个cell来就能够提供五个子控件供我们使用。
在哪个地方可以以创建出来就拥有某些东西呢?当然是在initwith初始化方法中完成(构造方法让我们的对象一创建出来就拥有某些东西),为了让我自定义的cell一创建出来就有三个imageview两个label,应该重写构造。系统自动填好(你很有可能会用到)。在构造方法中,让自定义的cell和系统的cell一样,以创建出来就拥有一些子控件提供给我们使用。
2在自定义cell部分的说明:
A.创建控件,添加并赋值给属性。
1.创建头像
2.创建昵称
3.创建vip
4创建正文
5.创建配图
注意点:uiimageview iconview名称不能写成是imageview(他的父类叫imageview,那么不能在子类中定义一个imageview,不然到时候它怎么知道是要调用哪个?不能和系统自带的重名)。
创建好之后,添加到contentview中。可以进入到头文件中查看注释:如果你自定义一个cell,如果要添加view的时候,建议添加到contentview中。
当在外部创建一个cell的时候,调用他的初始化构造方法,首先就来到构造方法中,添加5个控件到cell中。为什么不设置数据(系统的也没有设置数据)添加数据,将来设置模型的时候再添加。
B.如何设置数据?
在传递模型给他的时候,重写它的set方法,拿到外界传递进来的数据,给它设置数据就完了。
重写set方法:在set方法中,应该做两件事情。
(1)设置子控件的数据
(2)设置子控件的frame,因为如果不设置frame的话,子控件根本显示不出来。(不能在init方法中设置控件的frame)
逻辑:因为子控件的frame高度等是依赖于数据的,需要根据数据来确定,所以只能在拿到数据的时候才能设置子控件的frame,在下面的set方法中要拿到上面添加的控件,怎么拿?是否应该把上面的子控件通过属性保存一下。控件一般用weak,但是用strong也可以。通过属性保存之后,下面才能进行赋值。
提示:设置数据和设置frame是两个功能,应该把他们封装到两个方法中去。
【self settingDate】 vip的图片是不用变的
【self settingFrame】
四、实现思路整理
设置frame时的思路和一些注意点:
(1)
一个控件没有frame肯定显示不出来
设置frame的过程中需要从哪里入手呢?以后遇到要为很多控件设置frmae的时候。建议先找控件之间的关系,先找准一个固定不变的点,然后再计算不确定的控件的frmae.总要有一个点,再来计算其他的东西。
在这个应用中找到规律,先设置头像的,再设置其他的。
在真实开发中间隙等是由美工提供的。计算x,y,w,h等得值。分别计算所有控件的frame,注意这是依赖于数据的。
(2)
获取控件的最大值CGRectMaxX(SELF.ICONvIEW.FRAME)或取头像最大的x值。
在ios7中计算文字的宽度和高度?
需要传递一个字体。影响文本的宽度和高度的因素:(1)字体的大小;(2)存放文本的最大的范围。在计算文本的宽高时,应该告诉这两个。
_weibo.name sizewithFont:nil ios7以前的方法
ios7以后要传4个参数
boundingRectWthSize:(cgsize).....将来能够显示文本的范围,宽和高。
nsdictionary *dict=@{NSfontattributename:宏}
在创建昵称的时候就要告诉它,将来以15号的字体显示。(注意不要忘了这一点,否则计算出来的不准确)
不限制其宽度和高度的大小:MAXFLOAT
计算文本的宽高,把这个功能封装。接受三个参数,字符串,字体,Maxsize.返回值为CGSIZE.
需要计算的文本
文本显示的字体
文本显示的范围
文本占用的真实宽高。
注意:有关字体的计算,在创建的时候就要指定其将要显示的字号是多大。
内容文本的宽高和昵称不一样,正文会换行,那么就限制一下其宽度,不限制高度就可以了。
cell的高度不够,需要在viewdioad中设置cell的高度(大失所望)
默认label只显示一行。当创建正文的时候,还要设置让其自定换行。设置为0
(3)
如果没有配图的话就不计算它的宽高,把计算的过程放到if大括号里边。
设置配图的问题:有的又配图,有的没有配图(cell滚动离开视野放到缓存池中)。问题在于,如果需要一个没有配图的,这时候去缓存中去取,取到的是一个有配图的那不是就冲突了么?
如何解决这个问题:
在设置数据的时候进行判断,如果有配图,那么就设置数据,.hidden=no;
如果没有配图的话那就不让它显示。hidden=YES.
注意点:在tableview中有一个复用的问题,有显示就要有隐藏。这是一个陷阱。一定要记住。
(4)
所有的vip图标都是同一个,可以在init初始化方法中对vip图标进行设置。
此时出现了一个新的问题。所有的宽高计算一次就可以了,但是这里每次滚动都会调用计算,没有必要。
五、重要说明
IOS7以后计算文本的宽度和高度:
//4.设置正文的frame
CGFloat textLabX=iconViewX;
CGFloat textLabY=CGRectGetMaxY(self.iconView.frame)+padding;
CGSize textSize=[self sizeWithString:_weibo.text font:YYTextFont maxSize:CGSizeMake(300,MAXFLOAT)];
self.textLab.frame=CGRectMake(textLabX, textLabY, textSize.width, textSize.height);
这里把计算过程封装在了下面的方法中:
一、storyboard的处理
直接让控制器继承uitableview controller,然后在storyboard中把继承自uiviewcontroller的控制器干掉,重新拖一个tableview controller,和主控制器进行连线。
项目结构和plist文件
二、程序逻辑业务的处理
第一步,把配图和plist中拿到项目中,加载plist数据(非png的图片放到spooding files中)
第二步,字典转模型,完成plist中数据的加载。属性的注意点(number vip是bool类型,本质是整型的)kvc会智能的把nsnumber转换成bool型的。
第三步,懒加载。
第四步,有了数据之后直接实现数据源方法
(1)一共有几组(如果有一组的,那么可以不写,默认为一组)
(2)每组一共有多少行(数组有多少个元素,就有多少组)
(3)展示数据
1)到缓存中取cell
2)没有的话就创建
3)设置数据
4)返回cell
三、代码
视图部分
TXStatusCell.h文件
// 01-屌丝逆天之---微博 // // Created by 鑫 on 14-10-12. // Copyright (c) 2014年 梁镋鑫. All rights reserved. // #import <UIKit/UIKit.h> @class TXStatus; @interface TXStatusCell : UITableViewCell @property (nonatomic, strong) TXStatus *status; @end
TXStatusCell.m文件
// // 昵称的字体 #define TXNameFont [UIFont systemFontOfSize:14] // 正文的字体 #define TXTextFont [UIFont systemFontOfSize:15] #import "TXStatusCell.h" #import "TXStatus.h" @interface TXStatusCell() /** * 头像 */ @property (nonatomic, weak) UIImageView *iconView; /** * 昵称 */ @property (nonatomic, weak) UILabel *nameView; /** * 会员图标 */ @property (nonatomic, weak) UIImageView *vipView; /** * 正文 */ @property (nonatomic, weak) UILabel *textView; /** * 配图 */ @property (nonatomic, weak) UIImageView *pictureView; @end @implementation TXStatusCell /** * 构造方法(在初始化对象的时候会调用) * 一般在这个方法中添加需要显示的子控件 */ - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // 1.头像 UIImageView *iconView = [[UIImageView alloc] init]; [self.contentView addSubview:iconView]; self.iconView = iconView; // 2.昵称 UILabel *nameView = [[UILabel alloc] init]; // nameView.backgroundColor = [UIColor redColor]; nameView.font = TXNameFont; [self.contentView addSubview:nameView]; self.nameView = nameView; // 3.会员图标 UIImageView *vipView = [[UIImageView alloc] init]; vipView.image = [UIImage imageNamed:@"vip"]; [self.contentView addSubview:vipView]; self.vipView = vipView; // 4.正文 UILabel *textView = [[UILabel alloc] init]; // textView.backgroundColor = [UIColor blueColor]; textView.numberOfLines = 0; textView.font = TXTextFont; [self.contentView addSubview:textView]; self.textView = textView; // 5.配图 UIImageView *pictureView = [[UIImageView alloc] init]; [self.contentView addSubview:pictureView]; self.pictureView = pictureView; } return self; } /** * 在这个方法中设置子控件的frame和显示数据 */ - (void)setStatus:(TXStatus *)status { _status= status; // 1.设置数据 [self settingData]; // 2.设置frame [self settingFrame]; } /** * 设置数据 */ - (void)settingData { // 1.头像 self.iconView.image = [UIImage imageNamed:self.status.icon]; // 2.昵称 self.nameView.text = self.status.name; // 3.会员图标 if (self.status.vip) { self.vipView.hidden = NO; self.nameView.textColor = [UIColor redColor]; } else { self.vipView.hidden = YES; self.nameView.textColor = [UIColor blackColor]; } // 4.正文 self.textView.text = self.status.text; // 5.配图 if (self.status.picture) { // 有配图 self.pictureView.hidden = NO; self.pictureView.image = [UIImage imageNamed:self.status.picture]; } else { // 没有配图 self.pictureView.hidden = YES; } } /** * 计算文字尺寸 * * @param text 需要计算尺寸的文字 * @param font 文字的字体 * @param maxSize 文字的最大尺寸 */ - (CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize { NSDictionary *attrs = @{NSFontAttributeName : font}; return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrs context:nil].size; } /** * 设置frame */ - (void)settingFrame { // 子控件之间的间距 CGFloat padding = 10; // 1.头像 CGFloat iconX = padding; CGFloat iconY = padding; CGFloat iconW = 30; CGFloat iconH = 30; self.iconView.frame = CGRectMake(iconX, iconY, iconW, iconH); // 2.昵称 // 文字的字体,计算文字的宽度由字体大小也数量决定 CGSize nameSize = [self sizeWithText:self.status.name font:TXNameFont maxSize:CGSizeMake(MAXFLOAT, MAXFLOAT)]; CGFloat nameX = CGRectGetMaxX(self.iconView.frame) + padding; CGFloat nameY = iconY + (iconH - nameSize.height) * 0.5; self.nameView.frame = CGRectMake(nameX, nameY, nameSize.width, nameSize.height); // 3.会员图标 CGFloat vipX = CGRectGetMaxX(self.nameView.frame) + padding; CGFloat vipY = nameY; CGFloat vipW = 14; CGFloat vipH = 14; self.vipView.frame = CGRectMake(vipX, vipY, vipW, vipH); // 4.正文 CGFloat textX = iconX; CGFloat textY = CGRectGetMaxY(self.iconView.frame) + padding; CGSize textSize = [self sizeWithText:self.status.text font:TXTextFont maxSize:CGSizeMake(300, MAXFLOAT)]; self.textView.frame = CGRectMake(textX, textY, textSize.width, textSize.height); // 5.配图 if (self.status.picture) {// 有配图 CGFloat pictureX = textX; CGFloat pictureY = CGRectGetMaxY(self.textView.frame) + padding; CGFloat pictureW = 100; CGFloat pictureH = 100; self.pictureView.frame = CGRectMake(pictureX, pictureY, pictureW, pictureH); } } - (void)awakeFromNib { // Initialization code } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state } @end
TXStatus.h文件
// 01-屌丝逆天之---微博 // // Created by 鑫 on 14-10-12. // Copyright (c) 2014年 梁镋鑫. All rights reserved. // #import <Foundation/Foundation.h> @interface TXStatus : NSObject @property (nonatomic, copy) NSString *text; // 内容 @property (nonatomic, copy) NSString *icon; // 头像 @property (nonatomic, copy) NSString *name; // 昵称 @property (nonatomic, copy) NSString *picture; // 配图 @property (nonatomic, assign) BOOL vip; - (instancetype)initWithDict:(NSDictionary *)dict; + (instancetype)statusWithDict:(NSDictionary *)dict; @end
TXStatus.m文件
// #import "TXStatus.h" #import "TXStatus.h" @implementation TXStatus - (instancetype)initWithDict:(NSDictionary *)dict { if (self = [super init]) { [self setValuesForKeysWithDictionary:dict]; } return self; } + (instancetype)statusWithDict:(NSDictionary *)dict { return [[self alloc] initWithDict:dict]; } @end
主控制器部分
TXViewControllerh文件
#import <UIKit/UIKit.h> @interface TXViewController : UITableViewController @end
TXViewController.m文件
#import "TXViewController.h" #import "TXStatus.h" #import "TXStatusCell.h" @interface TXViewController () @property (nonatomic, strong) NSArray *statuses; @end @implementation TXViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. //行高 self.tableView.rowHeight = 400; } - (NSArray *)statuses { if (_statuses == nil) { // 初始化 // 1.获得plist的全路径 NSString *path = [[NSBundle mainBundle] pathForResource:@"statuses.plist" ofType:nil]; // 2.加载数组 NSArray *dictArray = [NSArray arrayWithContentsOfFile:path]; // 3.将dictArray里面的所有字典转成模型对象,放到新的数组中 NSMutableArray *statusArray = [NSMutableArray array]; for (NSDictionary *dict in dictArray) { // 3.1.创建模型对象 TXStatus *status = [TXStatus statusWithDict:dict]; // 3.2.添加模型对象到数组中 [statusArray addObject:status]; } // 4.赋值 _statuses = statusArray; } return _statuses; } #pragma mark - 实现数据源方法 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.statuses.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *ID = @"status"; TXStatusCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; if (cell == nil) { cell = [[TXStatusCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:ID]; } cell.status = self.statuses[indexPath.row]; return cell; } - (BOOL)prefersStatusBarHidden { return YES; } @end
阶段性展示:
四、补充说明
1对于展示数据部分的补充说明:
设置数据的时候遇到新的问题:uitableviewcell默认只有一个imageview,一个tabletext和一个详细三个子控件可以用,但是这个微博至少有四个。系统提供的cell不能满足需求,那么我们就在系统提供的cell的基础上为它增加一些功能,新建一个类,自定义cell,让它继承自uitableviewcell。
不用系统的,用自己定义的cell,把自定义的cell头文件导入,还是先去缓存中找,如果找不到就创建一个自定义的cell。创建玩自定义cell后,就应该给cell设置数据,按照封装的思想,设置数据的时候,你把数据给我,我自己爱怎么设置就怎么设置。所以把当前的模型取出来,传递给我cell中得一个属性,我自己重写set方法完成赋值。在cell里面应该增加一个属性,用于接收传入的模型。
此时,应该赋值数据,并对系统原有的封装和操作进行分析。在以前创建的系统的cell一创建的时候默认就有三个子控件提供给我们使用。自定义的cell按照实际的需求(需要创建5个子控件),我们也应该以创建出一个cell来就能够提供五个子控件供我们使用。
在哪个地方可以以创建出来就拥有某些东西呢?当然是在initwith初始化方法中完成(构造方法让我们的对象一创建出来就拥有某些东西),为了让我自定义的cell一创建出来就有三个imageview两个label,应该重写构造。系统自动填好(你很有可能会用到)。在构造方法中,让自定义的cell和系统的cell一样,以创建出来就拥有一些子控件提供给我们使用。
2在自定义cell部分的说明:
A.创建控件,添加并赋值给属性。
1.创建头像
2.创建昵称
3.创建vip
4创建正文
5.创建配图
注意点:uiimageview iconview名称不能写成是imageview(他的父类叫imageview,那么不能在子类中定义一个imageview,不然到时候它怎么知道是要调用哪个?不能和系统自带的重名)。
创建好之后,添加到contentview中。可以进入到头文件中查看注释:如果你自定义一个cell,如果要添加view的时候,建议添加到contentview中。
当在外部创建一个cell的时候,调用他的初始化构造方法,首先就来到构造方法中,添加5个控件到cell中。为什么不设置数据(系统的也没有设置数据)添加数据,将来设置模型的时候再添加。
B.如何设置数据?
在传递模型给他的时候,重写它的set方法,拿到外界传递进来的数据,给它设置数据就完了。
重写set方法:在set方法中,应该做两件事情。
(1)设置子控件的数据
(2)设置子控件的frame,因为如果不设置frame的话,子控件根本显示不出来。(不能在init方法中设置控件的frame)
逻辑:因为子控件的frame高度等是依赖于数据的,需要根据数据来确定,所以只能在拿到数据的时候才能设置子控件的frame,在下面的set方法中要拿到上面添加的控件,怎么拿?是否应该把上面的子控件通过属性保存一下。控件一般用weak,但是用strong也可以。通过属性保存之后,下面才能进行赋值。
提示:设置数据和设置frame是两个功能,应该把他们封装到两个方法中去。
【self settingDate】 vip的图片是不用变的
【self settingFrame】
四、实现思路整理
设置frame时的思路和一些注意点:
(1)
一个控件没有frame肯定显示不出来
设置frame的过程中需要从哪里入手呢?以后遇到要为很多控件设置frmae的时候。建议先找控件之间的关系,先找准一个固定不变的点,然后再计算不确定的控件的frmae.总要有一个点,再来计算其他的东西。
在这个应用中找到规律,先设置头像的,再设置其他的。
在真实开发中间隙等是由美工提供的。计算x,y,w,h等得值。分别计算所有控件的frame,注意这是依赖于数据的。
(2)
获取控件的最大值CGRectMaxX(SELF.ICONvIEW.FRAME)或取头像最大的x值。
在ios7中计算文字的宽度和高度?
需要传递一个字体。影响文本的宽度和高度的因素:(1)字体的大小;(2)存放文本的最大的范围。在计算文本的宽高时,应该告诉这两个。
_weibo.name sizewithFont:nil ios7以前的方法
ios7以后要传4个参数
boundingRectWthSize:(cgsize).....将来能够显示文本的范围,宽和高。
nsdictionary *dict=@{NSfontattributename:宏}
在创建昵称的时候就要告诉它,将来以15号的字体显示。(注意不要忘了这一点,否则计算出来的不准确)
不限制其宽度和高度的大小:MAXFLOAT
计算文本的宽高,把这个功能封装。接受三个参数,字符串,字体,Maxsize.返回值为CGSIZE.
需要计算的文本
文本显示的字体
文本显示的范围
文本占用的真实宽高。
注意:有关字体的计算,在创建的时候就要指定其将要显示的字号是多大。
内容文本的宽高和昵称不一样,正文会换行,那么就限制一下其宽度,不限制高度就可以了。
cell的高度不够,需要在viewdioad中设置cell的高度(大失所望)
默认label只显示一行。当创建正文的时候,还要设置让其自定换行。设置为0
(3)
如果没有配图的话就不计算它的宽高,把计算的过程放到if大括号里边。
设置配图的问题:有的又配图,有的没有配图(cell滚动离开视野放到缓存池中)。问题在于,如果需要一个没有配图的,这时候去缓存中去取,取到的是一个有配图的那不是就冲突了么?
如何解决这个问题:
在设置数据的时候进行判断,如果有配图,那么就设置数据,.hidden=no;
如果没有配图的话那就不让它显示。hidden=YES.
注意点:在tableview中有一个复用的问题,有显示就要有隐藏。这是一个陷阱。一定要记住。
(4)
所有的vip图标都是同一个,可以在init初始化方法中对vip图标进行设置。
此时出现了一个新的问题。所有的宽高计算一次就可以了,但是这里每次滚动都会调用计算,没有必要。
五、重要说明
IOS7以后计算文本的宽度和高度:
//4.设置正文的frame
CGFloat textLabX=iconViewX;
CGFloat textLabY=CGRectGetMaxY(self.iconView.frame)+padding;
CGSize textSize=[self sizeWithString:_weibo.text font:YYTextFont maxSize:CGSizeMake(300,MAXFLOAT)];
self.textLab.frame=CGRectMake(textLabX, textLabY, textSize.width, textSize.height);
这里把计算过程封装在了下面的方法中:
/** * 计算文本的宽高 * * @param str 需要计算的文本 * @param font 文本显示的字体 * @param maxSize 文本显示的范围 * * @return 文本占用的真实宽高 */ - (CGSize)sizeWithString:(NSString *)str font:(UIFont *)font maxSize:(CGSize)maxSize { NSDictionary *dict = @{NSFontAttributeName : font}; // 如果将来计算的文字的范围超出了指定的范围,返回的就是指定的范围 // 如果将来计算的文字的范围小于指定的范围, 返回的就是真实的范围 CGSize size = [str boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:dict context:nil].size; return size; }
相关文章推荐
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(三·完结)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(一)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(三·完结)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(一) - 文顶顶
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(二)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(三·完结)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(二)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(二)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(二) - 文顶顶
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(三·完结) - 文顶顶
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(一)
- iOS开发UI篇—以微博界面为例使用纯代码自定义cell程序编码全过程(二)
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局
- ios开发UI篇—使用纯代码自定义UItableviewcell实现一个简单的微博界面布局