Plist文件 1、创建模型类FRGoods FRGoods.h
#import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface FRGoods : NSObject @property(nonatomic,copy)NSString* buyCount; @property(nonatomic,copy)NSString* price; @property(nonatomic,copy)NSString* title; @property(nonatomic,copy)NSString* icon; -(instancetype)initWithDictionary:(NSDictionary*)dict; +(instancetype)goodsWithDictionary:(NSDictionary*)dict; @end NS_ASSUME_NONNULL_ENDFRGoods.m
#import "FRGoods.h" //字典转模型 @implementation FRGoods -(instancetype)initWithDictionary:(NSDictionary*)dict{ if (self=[super init]) { [self setValuesForKeysWithDictionary:dict]; } return self; } +(instancetype)goodsWithDictionary:(NSDictionary*)dict{ return [[self alloc]initWithDictionary:dict]; } @end2、设置数据源,并在viewcontroller中实现
#import "ViewController.h" #import "FRGoods.h" @interface ViewController ()<UITableViewDataSource> @property (nonatomic,strong) NSArray* goods; @end @implementation ViewController //懒加载数据 //重写goods的get方法 -(NSArray*)goods{ if (_goods==nil) { //获取path路径 NSString* path=[[NSBundle mainBundle]pathForResource:@"tgs.plist" ofType:nil]; //从路径文件中加载字典 NSArray* arrydict=[NSArray arrayWithContentsOfFile:path]; //遍历字典数组 NSMutableArray *arrayModelM=[NSMutableArray array]; for (NSDictionary* dict in arrydict) { FRGoods* good=[FRGoods goodsWithDictionary:dict]; [arrayModelM addObject:good]; } //赋值数组 _goods=arrayModelM; } //返回goods return _goods; } //实现三个数据源方法 //实现分组数量 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } //实现分行数量 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return self.goods.count; } //返回单元格 -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //获取模型数据 FRGoods* model=self.goods[indexPath.row]; static NSString* strID=@"mycell"; UITableViewCell* cell=[tableView dequeueReusableCellWithIdentifier:strID]; if (cell==nil) { cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:strID]; //设置单元格数据 cell.textLabel.text=model.title; cell.imageView.image=[UIImage imageNamed:model.icon]; cell.detailTextLabel.text=[NSString stringWithFormat:@"¥ %@ %@人已经购买",model.price,model.buyCount]; } return cell; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. } @end结果:
Plist文件 1、创建模型类FRGoods FRGoods.h
#import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface FRGoods : NSObject //这个模型中包含了业务逻辑的各个属性(控件) @property(nonatomic,copy) NSString* buyCount; @property(nonatomic,copy) NSString* icon; @property(nonatomic,copy) NSString* price; @property(nonatomic,copy) NSString* title; //实例方法,使用字典实例化一个模型对象实例 -(instancetype)initWithDictionary:(NSDictionary*)dict; //类方法,使用字典实例化一个模型对象实例 +(instancetype)goodsWithDictionary:(NSDictionary*)dict; @end NS_ASSUME_NONNULL_ENDFRGoods.m
#import "FRGoods.h" @implementation FRGoods //创建模型,将字典值传递给模型中的属性 //实例方法,使用字典实例化一个模型对象实例 -(instancetype)initWithDictionary:(NSDictionary*)dict{ //通过父类实例化一个本类对象,并赋值给self,如果self不为空,则表达式为真 if (self=[super init]) { //使用字典中的键值分别给本类对象的各个属性数值 [self setValuesForKeysWithDictionary:dict]; } //返回本类对象 return self; } //类方法,使用字典实例化一个模型对象实例 +(instancetype)goodsWithDictionary:(NSDictionary*)dict{ //调用实例方法生成一个实例对象 return [[self alloc]initWithDictionary:dict]; } @end2、创建Xib文件FRGoodsCell.xib 在属性中进行进一步设置,设置对应的类为FRGoodsCell类,重用id为mycell 对xib中的文件在对应的FRGoodsCell类中拖线出各自属性
3、FRGoodsCell类对自定义xib进行设置 FRGoodsCell.h
#import <UIKit/UIKit.h> #import "FRGoods.h" NS_ASSUME_NONNULL_BEGIN @class GRGoods; @interface FRGoodsCell : UITableViewCell //设置一个模型属性给模型内部的控件赋值 @property (nonatomic,strong) FRGoods* mygoods; //封装一个类方法来创建单元格 +(instancetype)goodsCellWithTableView:(UITableView*) tableView; @end NS_ASSUME_NONNULL_ENDFRGoodsCell.m
#import "FRGoodsCell.h" @interface FRGoodsCell() @property (weak, nonatomic) IBOutlet UIImageView *imageViewIcon; @property (weak, nonatomic) IBOutlet UILabel *lblTitle; @property (weak, nonatomic) IBOutlet UILabel *lblPrice; @property (weak, nonatomic) IBOutlet UILabel *lblBuyCout; @end @implementation FRGoodsCell //重写mygoods的set方法 -(void)setMygoods:(FRGoods *)mygoods{ _mygoods=mygoods; //模型的数据设置给子控件 self.imageViewIcon.image=[UIImage imageNamed:mygoods.icon]; self.lblTitle.text=mygoods.title; self.lblPrice.text=[NSString stringWithFormat:@"¥ %@",mygoods.price ]; self.lblBuyCout.text=[NSString stringWithFormat:@"%@ 人已购买",mygoods.buyCount ]; } //封装一个类方法来创建单元格 +(instancetype)goodsCellWithTableView:(UITableView*) tableView{ //复用单元格 //复用单元格id static NSString* strID=@"myCell"; //创建单元格 FRGoodsCell *cell=[tableView dequeueReusableCellWithIdentifier:strID]; //如果单元格为空,则用复用标识符创建单元格cell if (cell==nil) { //cell=[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:strID]; cell=[[[NSBundle mainBundle]loadNibNamed:@"FRGoodsCell" owner:nil options:nil] firstObject]; } return cell; } - (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 } @end4、控制器进行简化 viewcontroller.h
#import "ViewController.h" #import "FRGoods.h" #import "FRGoodsCell.h" @interface ViewController ()<UITableViewDataSource> //创建一个模型数组用来存放模型, @property(nonatomic,strong) NSArray* goods;//这是用来存放FRGoods对象的数组 @property (weak, nonatomic) IBOutlet UITableView *myTableView; @end @implementation ViewController //懒加载数据 //重写数组的get方法 -(NSArray*)goods{ //初始化goods的内容,如果goods里面没有对象 if (_goods==nil) { //设置plist的路径 NSString* path=[[NSBundle mainBundle]pathForResource:@"tgs.plist" ofType:nil]; //设置字典数组来接受从path路径中解析出来的字典 NSArray* arrayDict=[NSArray arrayWithContentsOfFile:path]; //创建一个可变模型数组,将各个字典转成模型后,加入到可变模型数组中 NSMutableArray* modelsM=[NSMutableArray array]; //遍历字典数组,将遍历出来的字点转成模型 for (NSDictionary* dict in arrayDict) { //通过遍历出来的字典作为参数生成一个模型对象,该对象包含业务逻辑的各个属性(控件) FRGoods* model=[FRGoods goodsWithDictionary:dict]; //将模型一次装入模型数组中 [modelsM addObject:model]; } _goods=modelsM; } //返回模型数组 return _goods; } //实现数据源的三个方法 //返回tableView的分组数 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } //返回tableview的行数 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ //函数就是模型数组的长度 return self.goods.count; } //返回tableView的单元格 -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //获取模型数据 //1、通过索引书来获得特定行的特定模型 FRGoods* goodsModel=self.goods[indexPath.row]; //2、创建一个单元格 FRGoodsCell* cell=[FRGoodsCell goodsCellWithTableView:tableView]; //3、设置单元格数据 cell.mygoods=goodsModel; //4、返回单元格 return cell; } - (void)viewDidLoad { [super viewDidLoad]; self.myTableView.rowHeight=80; } @end效果:
在例2的基础上添加footerView,也使用xib的方法添加 1、添加xib文件FRFootView.xib 2、为该xib文件对应的FRFootView类 FRFootView.h
#import <UIKit/UIKit.h> @class FRFootView; NS_ASSUME_NONNULL_BEGIN //将代理协议写在.h头文件里即可 @protocol FRFootViewDelegate <NSObject> @required -(void)footerViewUpdateData:(FRFootView*)footerView; @end @interface FRFootView : UIView //创建一个代理的属性 @property(nonatomic,weak)id<FRFootViewDelegate> delegate; @end NS_ASSUME_NONNULL_ENDFRFootView.m
#import "FRFootView.h" #import "FRGoods.h" @interface FRFootView() @property (weak, nonatomic) IBOutlet UIView *watingView; @property (weak, nonatomic) IBOutlet UIButton *btnLoadMore; - (IBAction)btnLoadClick; @end @implementation FRFootView //设置加载更多按钮的单击事件 - (IBAction)btnLoadClick { //1、加载按钮 self.btnLoadMore.hidden=YES; //2、显示等待指示器和文字(其父view) self.watingView.hidden=NO; //调用代理方法实现数据更新方法 //调用代理方法之前,为了保证调用不出错,要先判断一下代理对象是否真实现了这个方法,如果真实现了这个方法再调用,否则不调用 if([self.delegate respondsToSelector:@selector(footerViewUpdateData:)]){ [self.delegate footerViewUpdateData:self]; } } @end3、在viewController控制器类中实现委托方法
#import "ViewController.h" #import "FRGoods.h" #import "FRGoodsCell.h" #import "FRFootView.h" //需要实现UITableViewDataSource和FRFootViewDelegate代理协议 @interface ViewController ()<UITableViewDataSource,FRFootViewDelegate> //创建一个模型数组用来存放模型, @property(nonatomic,strong) NSMutableArray* goods;//这是用来存放FRGoods对象的数组 @property (weak, nonatomic) IBOutlet UITableView *myTableView; @end @implementation ViewController //懒加载数据 //重写数组的get方法 -(NSMutableArray*)goods{ //初始化goods的内容,如果goods里面没有对象 if (_goods==nil) { //设置plist的路径 NSString* path=[[NSBundle mainBundle]pathForResource:@"tgs.plist" ofType:nil]; //设置字典数组来接受从path路径中解析出来的字典 NSArray* arrayDict=[NSArray arrayWithContentsOfFile:path]; //创建一个可变模型数组,将各个字典转成模型后,加入到可变模型数组中 NSMutableArray* modelsM=[NSMutableArray array]; //遍历字典数组,将遍历出来的字点转成模型 for (NSDictionary* dict in arrayDict) { //通过遍历出来的字典作为参数生成一个模型对象,该对象包含业务逻辑的各个属性(控件) FRGoods* model=[FRGoods goodsWithDictionary:dict]; //将模型一次装入模型数组中 [modelsM addObject:model]; } _goods=modelsM; } //返回模型数组 return _goods; } //实现数据源的三个方法 //返回tableView的分组数 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } //返回tableview的行数 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ //函数就是模型数组的长度 return self.goods.count; } //返回tableView的单元格 -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //获取模型数据 //1、通过索引书来获得特定行的特定模型 FRGoods* goodsModel=self.goods[indexPath.row]; //2、创建一个单元格 FRGoodsCell* cell=[FRGoodsCell goodsCellWithTableView:tableView]; //3、设置单元格数据 cell.mygoods=goodsModel; //4、返回单元格 return cell; } //实现FRFootView的代理方法 -(void)footerViewUpdateData:(FRFootView *)footerView{ //3、增加一条数据 //3.1创建一个新的模型对象 FRGoods* model=[[FRGoods alloc]init]; model.title=@"驴肉火烧"; model.price=@"6.0"; model.buyCount=@"100"; model.icon=@"37e4761e6ecf56a2d78685df7157f097"; //3.2把模型对象加入到控制器的goods集合(数组)中 [self.goods addObject:model]; //4刷新UITableView [self.myTableView reloadData]; } - (void)viewDidLoad { [super viewDidLoad]; self.myTableView.rowHeight=80; //设置UITableView的footerView /* UIButton* btn=[UIButton buttonWithType:UIButtonTypeContactAdd]; btn.backgroundColor=[UIColor grayColor]; self.myTableView.tableFooterView=btn; */ //通过xib设置UITableView的footerView FRFootView* footerView=[[[NSBundle mainBundle]loadNibNamed:@"FRFootView" owner:nil options:nil] firstObject]; //设置footerView的代理 footerView.delegate=self; self.myTableView.tableFooterView=footerView; } @end加载后
1、修改上例的FRFootView类,增加一个类方法来添加专职xib文件 FRFootView.h
#import <UIKit/UIKit.h> @class FRFootView; NS_ASSUME_NONNULL_BEGIN //将代理协议写在.h头文件里即可 @protocol FRFootViewDelegate <NSObject> @required -(void)footerViewUpdateData:(FRFootView*)footerView; @end @interface FRFootView : UIView //创建一个代理的属性 @property(nonatomic,weak)id<FRFootViewDelegate> delegate; +(instancetype)footViewAdd; @end NS_ASSUME_NONNULL_ENDFRFootView.m
#import "FRFootView.h" #import "FRGoods.h" @interface FRFootView() @property (weak, nonatomic) IBOutlet UIView *watingView; @property (weak, nonatomic) IBOutlet UIButton *btnLoadMore; - (IBAction)btnLoadClick; @end @implementation FRFootView //设置加载更多按钮的单击事件 - (IBAction)btnLoadClick { //1、加载按钮 self.btnLoadMore.hidden=YES; //2、显示等待指示器和文字(其父view) self.watingView.hidden=NO; //延迟1秒钟后再执行刷新动作 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ //调用代理方法实现数据更新方法 //调用代理方法之前,为了保证调用不出错,要先判断一下代理对象是否真实现了这个方法,如果真实现了这个方法再调用,否则不调用 if([self.delegate respondsToSelector:@selector(footerViewUpdateData:)]){ [self.delegate footerViewUpdateData:self]; } //4、隐藏“加载更多”按钮 self.btnLoadMore.hidden=NO; //5、显示等待期所在的那个UIView self.watingView.hidden=YES; }); } //创建一个类方法来加载xib文件 +(instancetype)footViewAdd{ //通过xib设置UITableView的footerView FRFootView* footerView=[[[NSBundle mainBundle]loadNibNamed:@"FRFootView" owner:nil options:nil] firstObject]; return footerView; } @end在ViewController控制器中修改 ViewController.m
#import "ViewController.h" #import "FRGoods.h" #import "FRGoodsCell.h" #import "FRFootView.h" //需要实现UITableViewDataSource和FRFootViewDelegate代理协议 @interface ViewController ()<UITableViewDataSource,FRFootViewDelegate> //创建一个模型数组用来存放模型, @property(nonatomic,strong) NSMutableArray* goods;//这是用来存放FRGoods对象的数组 @property (weak, nonatomic) IBOutlet UITableView *myTableView; @end @implementation ViewController //懒加载数据 //重写数组的get方法 -(NSMutableArray*)goods{ //初始化goods的内容,如果goods里面没有对象 if (_goods==nil) { //设置plist的路径 NSString* path=[[NSBundle mainBundle]pathForResource:@"tgs.plist" ofType:nil]; //设置字典数组来接受从path路径中解析出来的字典 NSArray* arrayDict=[NSArray arrayWithContentsOfFile:path]; //创建一个可变模型数组,将各个字典转成模型后,加入到可变模型数组中 NSMutableArray* modelsM=[NSMutableArray array]; //遍历字典数组,将遍历出来的字点转成模型 for (NSDictionary* dict in arrayDict) { //通过遍历出来的字典作为参数生成一个模型对象,该对象包含业务逻辑的各个属性(控件) FRGoods* model=[FRGoods goodsWithDictionary:dict]; //将模型一次装入模型数组中 [modelsM addObject:model]; } _goods=modelsM; } //返回模型数组 return _goods; } //实现数据源的三个方法 //返回tableView的分组数 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } //返回tableview的行数 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ //函数就是模型数组的长度 return self.goods.count; } //返回tableView的单元格 -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //获取模型数据 //1、通过索引书来获得特定行的特定模型 FRGoods* goodsModel=self.goods[indexPath.row]; //2、创建一个单元格 FRGoodsCell* cell=[FRGoodsCell goodsCellWithTableView:tableView]; //3、设置单元格数据 cell.mygoods=goodsModel; //4、返回单元格 return cell; } //实现FRFootView的代理方法 -(void)footerViewUpdateData:(FRFootView *)footerView{ //3、增加一条数据 //3.1创建一个新的模型对象 FRGoods* model=[[FRGoods alloc]init]; model.title=@"驴肉火烧"; model.price=@"6.0"; model.buyCount=@"100"; model.icon=@"37e4761e6ecf56a2d78685df7157f097"; //3.2把模型对象加入到控制器的goods集合(数组)中 [self.goods addObject:model]; //4刷新UITableView这个是刷新全部列表 [self.myTableView reloadData]; //局部行的刷新,只适用于总行数没有变化的情况 //NSIndexPath* idxPath=[NSIndexPath indexPathForRow:self.goods.count-1 inSection:0]; //[self.myTableView reloadRowsAtIndexPaths:idxPath withRowAnimation:UITableViewRowAnimationLeft]; //把UITableView的最后一行的数据向上滚动 NSIndexPath* idxPath=[NSIndexPath indexPathForRow:self.goods.count-1 inSection:0]; [self.myTableView scrollToRowAtIndexPath:idxPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; } - (void)viewDidLoad { [super viewDidLoad]; self.myTableView.rowHeight=80; //设置UITableView的footerView FRFootView* footerView= [FRFootView footViewAdd]; //设置footerView的代理 footerView.delegate=self; self.myTableView.tableFooterView=footerView; } @end添加一个FRhead.xib文件作为头部的呈现,并指定FRHeader作为对应的类 FRHead类FRHead.h
#import <UIKit/UIKit.h> NS_ASSUME_NONNULL_BEGIN @interface FRHeader : UIView +(instancetype)headViewAdd; @end NS_ASSUME_NONNULL_ENDFRHead类FRHead.m
#import "FRHeader.h" @interface FRHeader() @property (weak, nonatomic) IBOutlet UIScrollView *headerScrollerView; @end @implementation FRHeader //重写awakefromNib方法唤醒xib中的UIScrollView -(void)awakeFromNib{ //在这里对xib中的控件进行控制 //self.headerScrollerView.contentSize= } //增加headeView的类方法 +(instancetype)headViewAdd{ //创建 一个headView FRHeader* headerView=[[[NSBundle mainBundle]loadNibNamed:@"FRHeader" owner:nil options:nil] firstObject]; return headerView; } @end控制器类viewController.m
#import "ViewController.h" #import "FRGoods.h" #import "FRGoodsCell.h" #import "FRFootView.h" #import "FRHeader.h" //需要实现UITableViewDataSource和FRFootViewDelegate代理协议 @interface ViewController ()<UITableViewDataSource,FRFootViewDelegate> //创建一个模型数组用来存放模型, @property(nonatomic,strong) NSMutableArray* goods;//这是用来存放FRGoods对象的数组 @property (weak, nonatomic) IBOutlet UITableView *myTableView; @end @implementation ViewController //懒加载数据 //重写数组的get方法 -(NSMutableArray*)goods{ //初始化goods的内容,如果goods里面没有对象 if (_goods==nil) { //设置plist的路径 NSString* path=[[NSBundle mainBundle]pathForResource:@"tgs.plist" ofType:nil]; //设置字典数组来接受从path路径中解析出来的字典 NSArray* arrayDict=[NSArray arrayWithContentsOfFile:path]; //创建一个可变模型数组,将各个字典转成模型后,加入到可变模型数组中 NSMutableArray* modelsM=[NSMutableArray array]; //遍历字典数组,将遍历出来的字点转成模型 for (NSDictionary* dict in arrayDict) { //通过遍历出来的字典作为参数生成一个模型对象,该对象包含业务逻辑的各个属性(控件) FRGoods* model=[FRGoods goodsWithDictionary:dict]; //将模型一次装入模型数组中 [modelsM addObject:model]; } _goods=modelsM; } //返回模型数组 return _goods; } //实现数据源的三个方法 //返回tableView的分组数 -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ return 1; } //返回tableview的行数 -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ //函数就是模型数组的长度 return self.goods.count; } //返回tableView的单元格 -(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ //获取模型数据 //1、通过索引书来获得特定行的特定模型 FRGoods* goodsModel=self.goods[indexPath.row]; //2、创建一个单元格 FRGoodsCell* cell=[FRGoodsCell goodsCellWithTableView:tableView]; //3、设置单元格数据 cell.mygoods=goodsModel; //4、返回单元格 return cell; } //实现FRFootView的代理方法 -(void)footerViewUpdateData:(FRFootView *)footerView{ //3、增加一条数据 //3.1创建一个新的模型对象 FRGoods* model=[[FRGoods alloc]init]; model.title=@"驴肉火烧"; model.price=@"6.0"; model.buyCount=@"100"; model.icon=@"37e4761e6ecf56a2d78685df7157f097"; //3.2把模型对象加入到控制器的goods集合(数组)中 [self.goods addObject:model]; //4刷新UITableView这个是刷新全部列表 [self.myTableView reloadData]; //局部行的刷新,只适用于总行数没有变化的情况 //NSIndexPath* idxPath=[NSIndexPath indexPathForRow:self.goods.count-1 inSection:0]; //[self.myTableView reloadRowsAtIndexPaths:idxPath withRowAnimation:UITableViewRowAnimationLeft]; //把UITableView的最后一行的数据向上滚动 NSIndexPath* idxPath=[NSIndexPath indexPathForRow:self.goods.count-1 inSection:0]; [self.myTableView scrollToRowAtIndexPath:idxPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; } - (void)viewDidLoad { [super viewDidLoad]; self.myTableView.rowHeight=80; //设置UITableView的footerView //创建footerView FRFootView* footerView= [FRFootView footViewAdd]; //设置footerView的代理 footerView.delegate=self; self.myTableView.tableFooterView=footerView; //创建headerview FRHeader* headerView=[FRHeader headViewAdd]; self.myTableView.tableHeaderView=headerView; } @end