plist文件 1、直接拖拽一个UITableViewController控件 删除原有的View,以及相应的ViewController类,直接拖拽一个UITableViewController控件,并将其对应的类设置为FRTableViewController,这个类自动指定了UITableViewDatoSource和UITableViewDelegate协议通过继承UITableViewController来实现,而UITableViewController已经指定了这两个协议),此外,还自动指定了一个tableView的类属性,因此不再需要通过拖线的方式来指定tableView这个属性。
2、创建模型类FRWeibo FRWeibo.h
#import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN //建立数据模型 @interface FRWeibo : UIView @property(nonatomic,copy) NSString* text; @property(nonatomic,copy) NSString* icon; @property(nonatomic,copy) NSString* name; @property(nonatomic,copy) NSString* picture; @property(nonatomic,assign,getter=isVip) BOOL* vip; -(instancetype)initWithDictionary:(NSDictionary*)dict; +(instancetype)weiboWithDictionary:(NSDictionary*)dict; @end NS_ASSUME_NONNULL_ENDFRWeibo.m
#import "FRWeibo.h" @implementation FRWeibo -(instancetype)initWithDictionary:(NSDictionary*)dict{ if (self=[super init]) { [self setValuesForKeysWithDictionary:dict]; } return self; } +(instancetype)weiboWithDictionary:(NSDictionary*)dict{ return [[self alloc]initWithDictionary:dict]; } @end3、FRTableViewController类
#import "FRTableViewController.h" #import "FRWeibo.h" @interface FRTableViewController () @property(nonatomic,strong)NSArray* weibo; @end @implementation FRTableViewController //懒加载数据 //重写weibo的get方法 -(NSArray*)getWeibo{ if (_weibo==nil) { //获取plist文件地址 NSString* path=[[NSBundle mainBundle]pathForResource:@"weibos.plist" ofType:nil]; //创建字典数组,从文件中获取字典 NSArray* arraydict=[NSArray arrayWithContentsOfFile:path]; //创建可变模型数组 NSMutableArray* modelM=[NSMutableArray array]; //遍历字典数组,并转换成模型,一次添加到模型数组中 for (NSDictionary* dict in arraydict) { //创建模型 FRWeibo* modelWeibo=[FRWeibo weiboWithDictionary:dict]; [modelM addObject:modelWeibo]; } //将模型数组赋值给属性 _weibo=modelM; } //返回类属性weibo return _weibo; } - (void)viewDidLoad { [super viewDidLoad]; } #pragma mark - Table view data source - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.weibo.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //创建单元格 static NSString* cellID=@"weibocellId";//单元格重用id UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"weibocellId" forIndexPath:indexPath];//重用单元格 if(cell==nil){ cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"weibocellId"]; } //获取模型数据 FRWeibo* weibocell=self.weibo[indexPath.row]; //给单元格各个控件赋值,通过模型传递 //cell.model=weibocell; return cell; } @end1、数据模型FRWeibo FRWeibo.h
#import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN //建立数据模型 @interface FRWeibo : UIView @property(nonatomic,copy) NSString* text; @property(nonatomic,copy) NSString* icon; @property(nonatomic,copy) NSString* name; @property(nonatomic,copy) NSString* picture; @property(nonatomic,assign,getter=isVip) NSNumber* vip; -(instancetype)initWithDictionary:(NSDictionary*)dict; +(instancetype)weiboWithDictionary:(NSDictionary*)dict; @end NS_ASSUME_NONNULL_ENDFRWeibo.m
#import "FRWeibo.h" @implementation FRWeibo -(instancetype)initWithDictionary:(NSDictionary*)dict{ if (self=[super init]) { [self setValuesForKeysWithDictionary:dict]; } return self; } +(instancetype)weiboWithDictionary:(NSDictionary*)dict{ return [[self alloc]initWithDictionary:dict]; } @end2、表格单元格FRTableViewCell类 FRTableViewCell.h
#import <UIKit/UIKit.h> //#import "FRWeibo.h" @class FRWeibo; NS_ASSUME_NONNULL_BEGIN @interface FRTableViewCell : UITableViewCell @property(nonatomic,strong)FRWeibo* weibo; @end NS_ASSUME_NONNULL_ENDFRTableViewCell.m
#import "FRTableViewCell.h" #import "FRWeibo.h" #define nameFont [UIFont systemFontOfSize:17] #define nameFontText [UIFont systemFontOfSize:13] @class FRWeibo; @interface FRTableViewCell() //创建个控件属性,头像,昵称,正文,配图,vip,方便调用 @property(nonatomic,weak)UIImageView* imgViewIcon; @property(nonatomic,weak)UIImageView* imgVip; @property(nonatomic,weak)UILabel* lblNickName; @property(nonatomic,weak)UILabel* lblText; @property(nonatomic,weak)UIImageView* imgViewPicture; @end @implementation FRTableViewCell //重写weibo属性的set方法 -(void)setWeibo:(FRWeibo *)weibo{ _weibo=weibo; //设置当前单元格中的子控件的数据 [self setMyData]; //设置当前单元格中的子控件的frame [self setMyFrame]; } //设置数据的方法 -(void)setMyData{ FRWeibo* model=self.weibo; self.imgViewIcon.image=[UIImage imageNamed:model.icon];//设置头像 if (model.picture) { //有配图 self.imgViewPicture.image=[UIImage imageNamed:model.picture];//设置配图 self.imgViewPicture.hidden=NO; }else{ self.imgViewPicture.hidden=YES; } //设置vip图片是否显示,vip在创建单元格的时候完成 if (model.isVip) { self.imgVip.hidden=NO; }else{ self.imgVip.hidden=YES; } self.lblNickName.text=model.name; self.lblText.text=model.text; } //设置frame的方法 -(void)setMyFrame{ //设置各个控件的坐标 CGFloat margin=10; //1.头像 CGFloat iconW=35; CGFloat iconH=35; CGFloat iconX=margin; CGFloat iconY=margin; self.imgViewIcon.frame=CGRectMake(iconX, iconY, iconW, iconH); //2.昵称 //获取昵称字符串 NSString *nickName = self.lblNickName.text; CGFloat nameX = CGRectGetMaxX(self.imgViewIcon.frame) + margin; //根据Label中文字的内容,来动态计算Label的高和宽 CGSize nameSize=[self sizeWithText:nickName andMaxSize:CGSizeMake(MAXFLOAT, MAXFLOAT) andFont:nameFont]; CGFloat nameW=nameSize.width; CGFloat nameH=nameSize.height; CGFloat nameY=iconY+(iconH-nameH)/2; self.lblNickName.frame=CGRectMake(nameX, nameY, nameW, nameH); //3.会员 CGFloat vipW=10; CGFloat vipH=10; CGFloat vipX=CGRectGetMaxX(self.lblNickName.frame)+margin; CGFloat vipY=nameY; self.imgVip.frame=CGRectMake(vipX, vipY, vipW, vipH); //4.正文 CGFloat textX=iconX; CGFloat textY=CGRectGetMaxX(self.imgViewIcon.frame)+margin; CGSize textSize=[self sizeWithText:self.lblText.text andMaxSize:CGSizeMake(394, MAXFLOAT) andFont:nameFontText]; CGFloat textW=textSize.width; CGFloat textH=textSize.height; self.lblText.frame=CGRectMake(textX, textY, textW, textH); //5.配图 CGFloat picW=100; CGFloat picH=100; CGFloat picX=iconX; CGFloat picY=CGRectGetMaxX(self.lblText.frame)+margin; self.imgViewPicture.frame=CGRectMake(picX, picY, picW, picH); //6.计算每行的高度 CGFloat rowHeight=0; if (self.weibo.picture) { //如果有配图,行高等于配图的最大Y值+margin rowHeight=CGRectGetMaxY(self.imgViewPicture.frame)+margin; }else{ //如果没有配图,行高等于正文的最大Y值+margin rowHeight=CGRectGetMaxY(self.lblText.frame)+margin; } } //计算文字size的方法,根据给定的字符串、最大字符串、给定的字体来计算文字应该占用的大小 -(CGSize)sizeWithText:(NSString*)text andMaxSize:(CGSize)maxSize andFont:(UIFont*)font{ NSDictionary* attr=@{NSFontAttributeName:nameFont}; return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attr context:nil].size;; } //重写initWithStyle方法初始化单元格内的各个控件 -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ if (self=[super initWithStyle:style reuseIdentifier:reuseIdentifier]) { //创建五个子控件,头像,昵称,会员,正文,配图 UIImageView* imgViewIcon=[[UIImageView alloc]init];//创建一个图像控件 [self.contentView addSubview:imgViewIcon]; self.imgViewIcon=imgViewIcon; UILabel* lblNickName=[[UILabel alloc]init]; [self.contentView addSubview:lblNickName]; lblNickName.font=nameFont;//设置正文的字体大小 self.lblNickName=lblNickName; UIImageView* imgVip=[[UIImageView alloc]init]; imgVip.image=[UIImage imageNamed:@"vip"];//设置vip [self.contentView addSubview:imgVip]; self.imgVip=imgVip; UILabel* lblText=[[UILabel alloc]init]; [self.contentView addSubview:lblText]; //设置正文文本可以自动换行 lblText.numberOfLines=0; self.lblText=lblText; UIImageView* imgViewPicture=[[UIImageView alloc]init]; [self.contentView addSubview:imgViewPicture]; self.imgViewPicture=imgViewPicture; } return self; } - (void)awakeFromNib { [super awakeFromNib]; // Initialization code } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state } @end3、表格控制器类FRTableViewController FRTableViewController.m
#import "FRTableViewController.h" #import "FRWeibo.h" #import "FRTableViewCell.h" @interface FRTableViewController () @property(nonatomic,strong)NSArray* weibos; @end @implementation FRTableViewController //懒加载数据 //重写weibo的get方法 -(NSArray*)weibos{ if (_weibos==nil) { //获取plist文件地址 NSString* path=[[NSBundle mainBundle]pathForResource:@"weibos.plist" ofType:nil]; //创建字典数组,从文件中获取字典 NSArray* arraydict=[NSArray arrayWithContentsOfFile:path]; //创建可变模型数组 NSMutableArray* modelM=[NSMutableArray array]; //遍历字典数组,并转换成模型,一次添加到模型数组中 for (NSDictionary* dict in arraydict) { //创建模型 FRWeibo* modelWeibo=[FRWeibo weiboWithDictionary:dict]; [modelM addObject:modelWeibo]; } //将模型数组赋值给属性 _weibos=modelM; } //返回类属性weibo return _weibos; } - (void)viewDidLoad { [super viewDidLoad]; //self.tableView.rowHeight=300; } #pragma mark - Table view data source //返回分组 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } //返回行数 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.weibos.count; } //返回单元格 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //获取模型数据 FRWeibo* weibocell=self.weibos[indexPath.row]; //创建单元格 static NSString* cellID=@"weibocellId";//单元格重用id FRTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];//重用单元格 if(cell==nil){ cell=[[FRTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID]; } //给单元格各个控件赋值,通过模型传递 cell.weibo=weibocell; return cell; } //代理方法,返回每行的行高的方法 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 300; } @end结果:
1、模型FRWeibo FRWeibo.h
#import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN //建立数据模型 @interface FRWeibo : UIView @property(nonatomic,copy) NSString* text; @property(nonatomic,copy) NSString* icon; @property(nonatomic,copy) NSString* name; @property(nonatomic,copy) NSString* picture; @property(nonatomic,assign,getter=isVip) NSNumber* vip; -(instancetype)initWithDictionary:(NSDictionary*)dict; +(instancetype)weiboWithDictionary:(NSDictionary*)dict; @end NS_ASSUME_NONNULL_ENDFRWeibo.m
#import "FRWeibo.h" @implementation FRWeibo -(instancetype)initWithDictionary:(NSDictionary*)dict{ if (self=[super init]) { [self setValuesForKeysWithDictionary:dict]; } return self; } +(instancetype)weiboWithDictionary:(NSDictionary*)dict{ return [[self alloc]initWithDictionary:dict]; } @end2、模型FRWeiboFrame FRWeiboFrame.h
#import <Foundation/Foundation.h> #import <CoreGraphics/CoreGraphics.h> #import <UIKit/UIkit.h> #define nameFont [UIFont systemFontOfSize:17] #define nameFontText [UIFont systemFontOfSize:13] NS_ASSUME_NONNULL_BEGIN @class FRWeibo; @interface FRWeiboFrame : NSObject @property(nonatomic,strong)FRWeibo* weibo; //添加frame的特有属性 //头像的frame @property(nonatomic,assign,readonly)CGRect iconFrame; //昵称的frame @property(nonatomic,assign,readonly)CGRect nameFrame; //vip的frame @property(nonatomic,assign,readonly)CGRect vipFrame; //正文的frame @property(nonatomic,assign,readonly)CGRect textFrame; //配图的frame @property(nonatomic,assign,readonly)CGRect picFrame; //行高 @property(nonatomic,assign,readonly)CGFloat rowHeight; @end NS_ASSUME_NONNULL_ENDFRWeiboFrame.m
#import "FRWeiboFrame.h" #import "FRWeibo.h" #define nameFont [UIFont systemFontOfSize:17] #define nameFontText [UIFont systemFontOfSize:13] @implementation FRWeiboFrame //重写weibo属性(微博数据)的set方法 -(void)setWeibo:(FRWeibo *)weibo{ _weibo=weibo; //计算每个空间的frame和行高 //设置各个控件的坐标 CGFloat margin=10; //1.头像 CGFloat iconW=35; CGFloat iconH=35; CGFloat iconX=margin; CGFloat iconY=margin; _iconFrame=CGRectMake(iconX, iconY, iconW, iconH); //2.昵称 //获取昵称字符串 NSString *nickName =_weibo.name; CGFloat nameX = CGRectGetMaxX(_iconFrame) + margin; //根据Label中文字的内容,来动态计算Label的高和宽 CGSize nameSize=[self sizeWithText:nickName andMaxSize:CGSizeMake(MAXFLOAT, MAXFLOAT) andFont:nameFont]; CGFloat nameW=nameSize.width; CGFloat nameH=nameSize.height; CGFloat nameY=iconY+(iconH-nameH)/2; _nameFrame=CGRectMake(nameX, nameY, nameW, nameH); //3.会员 CGFloat vipW=10; CGFloat vipH=10; CGFloat vipX=CGRectGetMaxX(_nameFrame)+margin; CGFloat vipY=nameY; _vipFrame=CGRectMake(vipX, vipY, vipW, vipH); //4.正文 CGFloat textX=iconX; CGFloat textY=CGRectGetMaxX(_iconFrame)+margin; CGSize textSize=[self sizeWithText:_weibo.text andMaxSize:CGSizeMake(394, MAXFLOAT) andFont:nameFontText]; CGFloat textW=textSize.width; CGFloat textH=textSize.height; _textFrame=CGRectMake(textX, textY, textW, textH); //5.配图 CGFloat picW=100; CGFloat picH=100; CGFloat picX=iconX; CGFloat picY=CGRectGetMaxX(_textFrame)+margin; _picFrame=CGRectMake(picX, picY, picW, picH); //6.计算每行的高度 CGFloat rowHeight=0; if (self.weibo.picture) { //如果有配图,行高等于配图的最大Y值+margin rowHeight=CGRectGetMaxY(_picFrame)+margin; }else{ //如果没有配图,行高等于正文的最大Y值+margin rowHeight=CGRectGetMaxY(_textFrame)+margin; } _rowHeight=rowHeight; } //计算文字size的方法,根据给定的字符串、最大字符串、给定的字体来计算文字应该占用的大小 -(CGSize)sizeWithText:(NSString*)text andMaxSize:(CGSize)maxSize andFont:(UIFont*)font{ NSDictionary* attr=@{NSFontAttributeName:nameFont}; return [text boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attr context:nil].size;; } @end3、单元格FRTableViewCell类 FRTableViewCell.h
#import <UIKit/UIKit.h> //#import "FRWeibo.h" #import "FRWeiboFrame.h" @class FRWeibo; @class FRWeiboFrame; NS_ASSUME_NONNULL_BEGIN @interface FRTableViewCell : UITableViewCell @property(nonatomic,strong)FRWeiboFrame* weiboFrame; +(instancetype)weiboCellWtihTableView:(UITableView*)tableView; @end NS_ASSUME_NONNULL_ENDFRTableViewCell.m
#import "FRTableViewCell.h" #import "FRWeibo.h" #import "FRWeiboFrame.h" #define nameFont [UIFont systemFontOfSize:17] #define nameFontText [UIFont systemFontOfSize:13] @class FRWeibo; @interface FRTableViewCell() //创建个控件属性,头像,昵称,正文,配图,vip,方便调用 @property(nonatomic,weak)UIImageView* imgViewIcon; @property(nonatomic,weak)UIImageView* imgVip; @property(nonatomic,weak)UILabel* lblNickName; @property(nonatomic,weak)UILabel* lblText; @property(nonatomic,weak)UIImageView* imgViewPicture; @end @implementation FRTableViewCell //重写weiboFrame属性的set方法 -(void)setWeiboFrame:(FRWeiboFrame *)weiboFrame{ _weiboFrame=weiboFrame; //设置当前单元格中的子控件的数据 [self setMyData]; //设置当前单元格中的子控件的frame [self setMyFrame]; } //设置数据的方法 -(void)setMyData{ FRWeibo* model=self.weiboFrame.weibo; self.imgViewIcon.image=[UIImage imageNamed:model.icon];//设置头像 if (model.picture) { //有配图 self.imgViewPicture.image=[UIImage imageNamed:model.picture];//设置配图 self.imgViewPicture.hidden=NO; }else{ self.imgViewPicture.hidden=YES; } //设置vip图片是否显示,vip在创建单元格的时候完成 if (model.isVip) { //设置显示会员图片 self.imgVip.hidden=NO; //设置昵称颜色为红色 self.lblNickName.textColor=[UIColor redColor]; }else{ self.imgVip.hidden=YES; self.lblNickName.textColor=[UIColor blackColor]; } self.lblNickName.text=model.name; self.lblText.text=model.text; } //设置frame的方法 -(void)setMyFrame{ //设置各个控件的坐标 //1.头像 self.imgViewIcon.frame=self.weiboFrame.iconFrame; //2.昵称 //获取昵称字符串 self.lblNickName.frame=self.weiboFrame.nameFrame; //3.会员 self.imgVip.frame=self.weiboFrame.vipFrame; //4.正文 self.lblText.frame=self.weiboFrame.textFrame; //5.配图 self.imgViewPicture.frame=self.weiboFrame.picFrame; } //重写initWithStyle方法初始化单元格内的各个控件 -(instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier{ if (self=[super initWithStyle:style reuseIdentifier:reuseIdentifier]) { //创建五个子控件,头像,昵称,会员,正文,配图 UIImageView* imgViewIcon=[[UIImageView alloc]init];//创建一个图像控件 [self.contentView addSubview:imgViewIcon]; self.imgViewIcon=imgViewIcon; UILabel* lblNickName=[[UILabel alloc]init]; [self.contentView addSubview:lblNickName]; lblNickName.font=nameFont;//设置正文的字体大小 self.lblNickName=lblNickName; UIImageView* imgVip=[[UIImageView alloc]init]; imgVip.image=[UIImage imageNamed:@"vip"];//设置vip [self.contentView addSubview:imgVip]; self.imgVip=imgVip; UILabel* lblText=[[UILabel alloc]init]; [self.contentView addSubview:lblText]; //设置正文文本可以自动换行 lblText.numberOfLines=0; self.lblText=lblText; UIImageView* imgViewPicture=[[UIImageView alloc]init]; [self.contentView addSubview:imgViewPicture]; self.imgViewPicture=imgViewPicture; } return self; } - (void)awakeFromNib { [super awakeFromNib]; // Initialization code } - (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated]; // Configure the view for the selected state } +(instancetype)weiboCellWtihTableView:(UITableView*)tableView{ //创建单元格 static NSString* cellID=@"weibocellId";//单元格重用id FRTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];//重用单元格 if(cell==nil){ cell=[[FRTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellID]; } return cell; } @end4、控制器FRTableViewController类 FRTableViewController.m
#import "FRTableViewController.h" #import "FRWeibo.h" #import "FRTableViewCell.h" #import "FRWeiboFrame.h" @interface FRTableViewController () //保存FRWeiboFrame模型的数组,因为frame数据模型里包含的控件大小高低的数据 @property(nonatomic,strong)NSArray* weiboFrames; @end @implementation FRTableViewController //懒加载数据 //重写weibo的get方法 -(NSArray*)weibos{ if (_weiboFrames==nil) { //获取plist文件地址 NSString* path=[[NSBundle mainBundle]pathForResource:@"weibos.plist" ofType:nil]; //创建字典数组,从文件中获取字典 NSArray* arraydict=[NSArray arrayWithContentsOfFile:path]; //创建可变模型数组 NSMutableArray* modelM=[NSMutableArray array]; //遍历字典数组,并转换成模型,一次添加到模型数组中 for (NSDictionary* dict in arraydict) { //创建模型 FRWeibo* modelWeibo=[FRWeibo weiboWithDictionary:dict]; //创建一个frame模型 FRWeiboFrame* modelWeiboFrame=[[FRWeiboFrame alloc]init]; //把数据模型赋值给了modelWeiboFrame中的微博属 modelWeiboFrame.weibo=modelWeibo; [modelM addObject:modelWeiboFrame]; } //将模型数组赋值给属性 _weiboFrames=modelM; } //返回类属性weibo return _weiboFrames; } - (void)viewDidLoad { [super viewDidLoad]; //self.tableView.rowHeight=300; } #pragma mark - Table view data source //返回分组 - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { return 1; } //返回行数 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.weiboFrames.count; } //返回单元格 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { //获取模型数据 FRWeiboFrame* weibocell=self.weiboFrames[indexPath.row]; //创建单元格 FRTableViewCell* cell=[FRTableViewCell weiboCellWtihTableView:tableView]; //给单元格各个控件赋值,通过模型传递 cell.weiboFrame=weibocell; return cell; } //代理方法,返回每行的行高的方法 -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ FRWeiboFrame* weiboFrame=self.weiboFrames[indexPath.row]; return weiboFrame.rowHeight ; } @end结果: 可惜最后没有实现,太晚了,不改了。