一、UITableViewCell简介
UITableView上的每一行的内容都是UITableViewCell来显示的,通过 UITableViewDataSource的协议方法:tableView:cellForRowAtIndexPath:来初始化要显示的内容。而 UITableViewCell则是通过它自带的contentView来显示,每个Cell都默认有个子视图contentView,所以每个cell 上显示的内容都是加在这个视图上。
系统的UITableViewCell有四种类型
UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle
这四种类型自己尝试一下看看有什么不同,开发一般很少会用的到,因为系统的满足不了我们的需求,所以我们经常会自定义UITableViewCell
UITableView的一些属于:
有时候我们会发现很多UITableViewCell右侧可以显示不同的图标,在iOS中称之为访问器,点击可以触发不同的事件,例如iPhone系统的设置
要设置这些图标只需要设置UITableViewCell的accesoryType属性,accesoryType是一个枚举类型,有以下几种类型:
typedef NS_ENUM(NSInteger, UITableViewCellAccessoryType) { UITableViewCellAccessoryNone, // 不显示任何图标 UITableViewCellAccessoryDisclosureIndicator, // 跳转指示图标 UITableViewCellAccessoryDetailDisclosureButton, // 内容详情图标和跳转指示图标 UITableViewCellAccessoryCheckmark, // 勾选图标 UITableViewCellAccessoryDetailButton NS_ENUM_AVAILABLE_IOS(7_0) // 内容详情图标 };
但是,你会发现没有第一个cell的accesoryType没有这种类型,其实只要设置UITableViewCell的accessoryView就可以让你的cell显示你想要的控件,只要是一个UIView都能支持
二、如何自定义UITableViewCell
1.首先要知道你想要显示怎么样的cell
2.将你需要显示的控件都定义成属性
3.因为开发的时候给cell赋值时一般都是有对应的model,所以最好写一个方法专门给cell赋值
4.因为我们自定义cell的时候可能会有很多控件,可以写一个类来计算这些控件的frame,然后写一个方法来给这些控件设置frame,最后可以在调用给cell赋值方法的时候一起调用这个方法
这里我简单的模仿一下QQ好友动态的frame的计算
#import <Foundation/Foundation.h> @interface MZQQModel : NSObject @property (nonatomic,copy) NSString *text; @property (nonatomic,copy) NSString *icon; @property (nonatomic,copy) NSString *name; @property (nonatomic,copy) NSString *picture; @property (nonatomic,copy) NSString *time; @property (nonatomic,copy) NSString *expert; @end #import <UIKit/UIKit.h> @class MZQQModel; @interface MZQQFrame : NSObject @property (nonatomic, strong) MZQQModel *qqModel; @property (nonatomic, assign, readonly) CGRect iconFrame; // 头像的frame @property (nonatomic, assign, readonly) CGRect nameFrame; // 昵称的frame @property (nonatomic, assign, readonly) CGRect timeFrame; // 时间的frame @property (nonatomic, assign, readonly) CGRect expertFrame; // QQ达人的Frame @property (nonatomic, assign, readonly) CGRect textFrame; // 正文的Frame @property (nonatomic, assign, readonly) CGRect pictureFrame; // 图片的Frame @property (nonatomic, assign, readonly) CGFloat rowHeight; // 总得高度 @end #import "MZQQFrame.h" #import "MZQQModel.h" #define MZNameFont 15 // 昵称字体的大小 #define MZTextFont 14 // 内容字体的大小 #define kScreenWidth [UIScreen mainScreen].bounds.size.width @implementation MZQQFrame //计算文字的大小 - (CGSize)sizeWithText:(NSString *)text maxSize:(CGSize)maxSize fontSize:(CGFloat)fontSize { //计算文本的大小 CGSize nameSize = [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]} context:nil].size; return nameSize; } - (void)setQqModel:(MZQQModel *)qqModel{ _qqModel = qqModel; CGFloat margin = 10; //头像 CGFloat iconW = 40; CGFloat iconH = 40; CGFloat iconX = margin; CGFloat iconY = margin; _iconFrame = CGRectMake(iconX, iconY, iconW, iconH); //昵称 CGSize nameSize = [self sizeWithText:self.qqModel.name maxSize:CGSizeMake(MAXFLOAT, MAXFLOAT) fontSize:MZNameFont]; CGFloat nameX = CGRectGetMaxX(_iconFrame) + margin; CGFloat nameY = iconY; _nameFrame = CGRectMake(nameX, nameY, nameSize.width, nameSize.height); //时间 CGSize timeSize = [self sizeWithText:self.qqModel.time maxSize:CGSizeMake(kScreenWidth - CGRectGetMidX(_pictureFrame), MAXFLOAT) fontSize:12]; CGFloat timeX = nameX; CGFloat timeY = CGRectGetMaxY(_nameFrame) + margin; _timeFrame = CGRectMake(timeX, timeY, timeSize.width, timeSize.height); //达人 CGFloat expertW = 14; CGFloat expertH = 14; CGFloat expertY = nameY; CGFloat expertX = CGRectGetMaxX(_nameFrame) + margin; _expertFrame = CGRectMake(expertX, expertY, expertW, expertH); //QQ内容 CGSize textSize = [self sizeWithText:self.qqModel.text maxSize:CGSizeMake(kScreenWidth - 2 * margin, MAXFLOAT) fontSize:MZTextFont]; CGFloat textX = iconX; CGFloat textY = CGRectGetMaxY(_iconFrame) + margin; _textFrame = CGRectMake(textX, textY, textSize.width, textSize.height); //QQ图片 (这里的图片大小给定了100,实际根据自己需求调整) if (self.qqModel.picture) { CGFloat pictureW = 100; CGFloat pictureH = 100; CGFloat pictureX = iconX; CGFloat pictureY = CGRectGetMaxY(_textFrame) + margin; _pictureFrame = (CGRect){{pictureX,pictureY},{pictureW,pictureH}}; _rowHeight = CGRectGetMaxY(_pictureFrame) + margin; }else{ _rowHeight = CGRectGetMaxY(_textFrame) + margin; } } @end #import <UIKit/UIKit.h> @class MZQQFrame; @interface MZQQCell : UITableViewCell @property (nonatomic, strong) MZQQFrame *qqFrame; @end #import "MZQQCell.h" #import "MZQQFrame.h" #import "MZQQModel.h" @interface MZQQCell () @property (nonatomic, strong) UIImageView *iconView; // 头像 @property (nonatomic, strong) UILabel *nameView; // 昵称 @property (nonatomic, strong) UILabel *timeView; // 时间 @property (nonatomic, strong) UIImageView *expertView; // 达人 @property (nonatomic, strong) UILabel *textView; // 正文 @property (nonatomic, strong) UIImageView *pictureView; // 图片 @end @implementation MZQQCell - (UIImageView *)iconView{ if (!_iconView) { _iconView = [[UIImageView alloc] init]; } return _iconView; } - (UILabel *)nameView{ if (!_nameView) { _nameView = [[UILabel alloc] init]; } return _nameView; } - (UILabel *)timeView{ if (!_timeView) { _timeView = [[UILabel alloc] init]; } return _timeView; } - (UIImageView *)expertView{ if (!_expertView) { _expertView = [[UIImageView alloc] init]; } return _expertView; } - (UILabel *)textView{ if (!_textView) { _textView = [[UILabel alloc] init]; } return _textView; } - (UIImageView *)pictureView{ if (!_pictureView) { _pictureView = [[UIImageView alloc] init]; } return _pictureView; } - (void)setQqFrame:(MZQQFrame *)qqFrame{ _qqFrame = qqFrame; //设置子控件显示的内容 [self setSubViewsContent]; //设置子控件的frame [self setSubViewsFrame]; } - (void)setSubViewsContent{ MZQQModel *qqModel = self.qqFrame.qqModel; self.iconView.image = [UIImage imageNamed:qqModel.icon]; self.nameView.text = qqModel.name; self.timeView.text = qqModel.time; // 如果qqModel.expert有值给图片 if (qqModel.expert) { self.expertView.hidden = NO; self.expertView.image = [UIImage imageNamed:qqModel.expert]; }else{ self.expertView.hidden = YES; } if (_pictureView) { self.pictureView.image = [UIImage imageNamed:qqModel.picture]; } } - (void)setSubViewsFrame{ self.iconView.frame = self.qqFrame.iconFrame; self.nameView.frame = self.qqFrame.nameFrame; self.timeView.frame = self.qqFrame.timeFrame; self.expertView.frame = self.qqFrame.expertFrame; self.textView.frame = self.qqFrame.textFrame; self.pictureView.frame = self.qqFrame.pictureFrame; }
上面都是一些计算frame的方法
其实计算frame并不是很难,只要你确定第一个控件的位置,你就可以根据第一个控件将其它控件的frame一一计算出来
当然,cell还有很多属性和方法,有兴趣的可以自己去研究研究