iOS开发-------模拟团购网站(UITableView 表格视图)以及自定义cell

news/2024/5/16 4:00:46/文章来源:https://blog.csdn.net/RunIntoLove/article/details/49071565

        上一篇博客说了UIScrollView(滚动视图),以及如何实现无限滚动的原理,那么这一次结合UIScrollView,以及UITableView(表格视图)做一个模拟团购的小Demon,并使用了xib以及加载pilsit文件,因为这个demon楼主做了比较久了,属于学iOS的初级demon,所以没有使用任何的约束,也没有任何的MVC思想,因为要想达到比较好的效果,用iPhone4或者IPhone4s的3.5英寸的屏幕观看,效果如下



Model类

为何会出现model类,那么请看一下plist文件



总体是一个数组,每一个数组元素是一个字典,那么字典其实就可以看做一个model,so,model类就非常简单了,Food类如下

#import <UIKit/UIKit.h>@interface Food : NSObject@property(nonatomic,strong) NSString * icon;//图片路径
@property(nonatomic,strong) NSString * name;//图片名
@property(nonatomic,strong) NSString * price;//价格
@property(nonatomic,strong) NSString * buyCount;//购买人数-(instancetype)initWithDict:(NSDictionary *)dic;//便利构造器
+(instancetype)foodWithDict:(NSDictionary *)dic;@end


实现文件也就这两个方法

- (instancetype)initWithDict:(NSDictionary *)dic
{self = [super init];if (self){//通过KVC简易赋值[self setValuesForKeysWithDictionary:dic];}return self;
}+ (instancetype)foodWithDict:(NSDictionary *)dic
{__autoreleasing Food * food = [[Food alloc]initWithDict:dic];return food;
}


HeadView(表格视图的表头视图,即滚动视图)

因为用的xib,那么什么是xib呢,在storyboard出现之前,与storyboard的作用类似,为了方便做视图上的布局,当然现在有了storyboard,功能会比xib强得多,但xib也要会,就当做练习一下。
介绍一下xib如何创建,NewFile - > User Interface - > Empty即可,一般情况下,与绑定的类命名是相同的,为了方便看




首先看一下表头的xib文件,上面是一个UIScrollView(滚动视图),中间是一个view,只不过宽度是1,所以看起来像一条线,最下面是一个label,用来显示文字“猜您喜欢”的。绑定类的位置也已经做了标注,不要绑定错了。


   


在声明文件中.h需要声明一个属性以及一个方法,如下
//
//  HeadLoad.h
//  团购网站
//
//  Created by YueWen on 15/9/1.
//  Copyright (c) 2015年 YueWen. All rights reserved.
//#import <UIKit/UIKit.h>@interface HeadLoad : UIView@property(nonatomic,assign,readonly) NSInteger numberOfImage;//scrollView中图片的数量-(instancetype)loadHeadView:(NSArray *)arrayImage;//加载ScrollView的图片@end



在实现文件中拖入输出口,并且加入一个计时器(NSTimer)的属性,如下
@interface HeadLoad ()<UIScrollViewDelegate>@property (strong, nonatomic) IBOutlet UIScrollView *scrollView;@property (strong, nonatomic) IBOutlet UIPageControl *pageControl;@property (strong,nonatomic) NSTimer * timer;@end



因为这一部分与上一篇中的描述是一样的,所以不再做过多的解释,如想了解一下UIScrollView以及无限循环请去前一篇博客瞅瞅,3Q    iOS学习-------滚动视图(UIScrollView)并实现循环滚动

这一部分有一个特别需要提及的,就是当滑动数值的tableView的时候,tableView的优先级很高,计时器由于优先级不够,所以会被抛弃,也就是不会执行timer,这里就需要几句话,提高一下timer的优先级
//提高timer的优先级
NSRunLoop * runLoop = [NSRunLoop currentRunLoop];//获得当前的运行池,现在看来和用子线程是一样的,只不过这个是将timer添加到了主线程中
[runLoop addTimer:self.timer forMode:NSRunLoopCommonModes];



其他的就不多说了。


FootView (加载更多)

依旧是xib构造,思路是在最下层有一个风火轮(Action Indicator),也就是那么转的东西,还有一个label上显示着努力加载中,最上面是一层view,覆盖住下面的风火轮以及label,只有当点击的时候,最上面的按钮隐藏,所以会出现转的风火轮以及正在努力加载的label,依旧不要忘记绑定类,



但是他麻烦就麻烦在,点击加载更多的时候,需要tableView来刷新列表,那么这个footView中没有tableView,用到其他view的组件,所以就用到了回调,楼主用的是委托回调

所以在声明文件中声明一个协议
@protocol FootLoadDelegate <NSObject>@required//必须有-(void)loadData:(FootLoad *)foodLoad;//加载数据@end

如果有协议,那么必然会存在一个协议属性delegate,可以是任何类型,唯一的条件就是必须履行协议,代理属性如下
@property(nonatomic,weak)id<FootLoadDelegate> delegate;

稍微麻烦点的东西就在实现文件中,其实也不难,首先将button组件拖入FootView,形成输出口
@interface FootLoad ()@property (strong, nonatomic) IBOutlet UIButton *footLoadLoadMore;//加载更多的按钮
@property (strong, nonatomic) IBOutlet UIView *footLoadLabelView;//最下层贴着label以及烽火轮的view@end

实现方法中只需要两个方法即可,一个是button的点击事件,一个是协议的方法

button的回调事件如下
//为按钮点击进行监听
- (IBAction)clickLoadMoreButton
{self.footLoadLabelView.hidden = NO;//努力加载以及风火轮出现self.footLoadLoadMore.hidden = YES;//加载更多的按钮隐藏//通过GCD延迟1.5秒后运行dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{//执行代理的loadData方法[self.delegate loadData:self];//时间到self.footLoadLoadMore.hidden = NO;//加载更多的按钮出现self.footLoadLabelView.hidden = YES;//努力加载以及风火轮被覆盖});}

协议方法如下
-(void)loadData:(FootLoad *)foodLoad
{//如果代理遵守了协议,即重写了loadData方法if (![self.delegate respondsToSelector:@selector(loadData:)]){//执行代理的方法[self.delegate loadData:self];}}


自定义cell

自定义的cell也是用xib做的,和storyboard一样用,拖入一个UITableViewCell,在上面布局即可




首先声明文件中声明外界调用的方法,用于设置cell的各个属性
-(void)setFood:(Food *)food;

输出口不在声明文件中,所以必然会在实现文件中的延展中,如下
@interface MyCell ()
@property (strong, nonatomic) IBOutlet UIImageView *myCellImageView;//显示图片的imageView
@property (strong, nonatomic) IBOutlet UILabel *myCellFoodName;//显示食物的名字
@property (strong, nonatomic) IBOutlet UILabel *myCellFoodPrice;//显示食物的价格
@property (strong, nonatomic) IBOutlet UILabel *myCellFoodBuyCount;//显示食物的购买人数
@end

接着实现setFood:方法即可
-(void)setFood:(Food *)food
{
self.myCellImageView.image = [UIImage imageNamed:[food icon]];
self.myCellFoodName.text = [food name];
self.myCellFoodPrice.text = [NSString stringWithFormat:@"¥ %@",[food price]];
self.myCellFoodBuyCount.text = [NSString stringWithFormat:@"%@ 人已经购买",[food buyCount]];
}


接着就是在自定义的类MyCell中拖入输出口,但是不希望外界修改,那么只给外界提供一个方法接口,传入一个Food类,直接打包好一个cell即可



ViewController(控制器)

首先延展中定义两个属性,一个是显示各个食物的tableView,一个是存储plist文件中的Food对象,如下
#import "ViewController.h"
#import "Food.h"
#import "MyCell.h"
#import "FootLoad.h"
#import "HeadLoad.h"@interface ViewController ()<UITableViewDataSource,UITableViewDelegate,FootLoadDelegate>@property(nonatomic,strong)UITableView * tableView;//显示食物的表格视图
@property(nonatomic,strong)NSMutableArray * foods;//存储所有的食物对象,因为可以添加,所以是可变数组
@end

       履行UITableViewDelegate协议以及UITableViewDataSource协议,是因为需要通过协议的方法设置tableView的显示属性,比较详细的tableView介绍可以去 iOS学习-------简单通讯录(UITableView和CoreData的应用)瞧一瞧


接着重写foods的getter方法,有的地方也喜欢叫做懒加载,就是说,只执行一次,如果foods没有值的时候,才会给它赋值,一旦有值了,也就是不为nil了,那么就直接返回,懒加载如下
#pragma mark - 懒加载
-(NSMutableArray *)foods
{NSMutableArray * array = [NSMutableArray array];//如果数据数组为nil的时候if (!_foods){//获得plist的文件路径NSString * path = [[NSBundle mainBundle] pathForResource:@"foods" ofType:@"plist"];//创建储存所有plist数据的数组NSArray * allData = [NSArray arrayWithContentsOfFile:path];//开始遍历数组,并添加数据for (NSDictionary * dic in allData){//创建模型Food * food = [Food foodWithDict:dic];[array addObject:food];}//为数据赋值_foods = array;}return _foods;
}

viewDidLoad如下,用来设置tableView的相关属性,以及设置表示图的表头视图和表尾视图
- (void)viewDidLoad {[super viewDidLoad];self.tableView = [[UITableView alloc] initWithFrame:self.view.frame style:UITableViewStylePlain];//设置tableView的格式为不分组self.tableView.rowHeight = 90;//每个cell的高度为90self.tableView.showsVerticalScrollIndicator = NO;//设置垂直指示器不显示[self.view addSubview:self.tableView];//设置数据源和代理对象self.tableView.delegate = self;self.tableView.dataSource = self;//加载最下侧的 加载更多 viewFootLoad * footView = [[[NSBundle mainBundle] loadNibNamed:@"FootLoad" owner:nil options:nil] firstObject];//加载xib中的组件用该方法,xib中可能右多个组件,所以会返回一个数组,自己做的xib里面只有一个组件,所以取第一个对象或者最后一个都可以//设置代理footView.delegate = self;self.tableView.tableFooterView = footView;//将tableView的footView设置成//加载最上侧的 scrollViewHeadLoad * headView = [[[NSBundle mainBundle] loadNibNamed:@"HeadLoad" owner:nil options:nil] firstObject];[headView loadHeadView:self.foods];self.tableView.tableHeaderView = headView;}

接着实现UItableViewDataSource的两个方法

#pragma mark - 实现UITableViewDataSource 方法
//返回一共多少行
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{//foods有多少个food对象既为多少行return self.foods.count;
}//返回cell
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{//创建 cell 的idstatic NSString * cellId = @"cellId";//根据id从缓冲池中查找CellMyCell * cell = [tableView dequeueReusableCellWithIdentifier:cellId];//如果没有查找到if (!cell){//从xib中加载cellcell = [[[NSBundle mainBundle] loadNibNamed:@"MyCell" owner:nil options:nil] firstObject];}//赋值[cell setFood:self.foods[indexPath.row]];return cell;}

履行footViewDelegate的方法,用于刷新当前的tableView
#pragma mark - 履行 FootLoadDelegate 的协议方法
-(void)loadData:(FootLoad *)foodLoad
{//随机的一个数字int random = arc4random()%(self.foods.count);//根据随机数字 取出模型foodFood * food = self.foods[random];//将 模型对象 添加到控制器的foods[self.foods addObject:food];//刷新tableView[self.tableView reloadData];//滚动数据NSIndexPath * indexPath = [NSIndexPath indexPathForRow:self.foods.count - 1 inSection:0];[self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:YES];//最下边的滚到最上面}

如果不想要上面那个显示电池的框,用下方法不显示
#pragma mark - 隐藏信息栏
-(BOOL)prefersStatusBarHidden
{return YES;
}




本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_893887.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python scrapy 爬取学习问答网站

废话不多说&#xff0c;直接入正题。 关于模拟登录&#xff0c;另一篇再讲解&#xff08;这篇写太多了&#xff09; 我们先来分析好页面。 首先打开知乎&#xff0c;点击进入首页的随便一个问答可以看到url是这样的&#x1f447; 观察url可以发现question有一个id&#xff0c…

分享几个免费书籍的网站

最近的博客更新有些迟钝&#xff0c;原因是在学前端设计的时候&#xff0c;发现Javascript 和 PHP 不是很融洽&#xff01; PHP 是后台&#xff0c;是一种 “穿插” 式语言&#xff1b;对学过其他程式语言人而言&#xff0c;只要了解怎么做输出就可以解决一大半的学习时间。 但…

新版Kali-2020版本介绍及image镜像网站

今天在安装新版的kali发现&#xff0c;现在的2020版本和之前的版本有些不一样。 首先&#xff0c;附上两个链接一个是网易的image镜像&#xff0c;一个是论坛 之前的阿里也有image镜像&#xff0c;现在他们改版了&#xff0c;我觉得不是很好用&#xff0c;刚好又找到网易的&…

bootstrap-自适应企业网站demo(一)

1.获取bootstrap文件 英文官网&#xff1a;http://getboostrap.com 中文官网&#xff1a;http://www.bootcss.xom 2.开发工具 开发工具选择WebStorm 3.创建基础文件 在WebStorm创建一个空的项目。 将下载的bootstrap文件解压&#xff0c;将文件夹下的css、fronts、js文件夹拷…

鼠标事件 onmouseover、onmouseenter、onmouseleave和onmouseout

触发时机&#xff1a; onmouseout&#xff1a;鼠标滑出 onmouseover&#xff1a;鼠标滑过&#xff08;在表面经过即可&#xff09; onmouseenter&#xff1a;鼠标进入&#xff08;进入到里面&#xff09; onmouseleave&#xff1a;鼠标离开 onmouseover 和 onmouseenter 的区…

黑客攻防技巧:2分钟入侵网站全程实录(组图)

说起流光、溯雪、乱刀&#xff0c;可以说是大名鼎鼎无人不知无人不晓&#xff0c;这些都是小榕哥的作品。每次一提起小榕哥来&#xff0c;我的崇拜景仰就如滔滔江水&#xff0c;连绵不绝 ~~~~(又来了!) 让我们崇拜的小榕哥最新又发布了SQL注入 工具 &#xff0c;这回喜欢利用S…

SQL Server 2005全文检索技术在网站上的应用实录

SQL Server 2005全文检索技术在网站上的应用实录(1) 一、前言 “人类失去搜索&#xff0c;世界将会怎样?”&#xff0c;同样&#xff0c;很难想象一个拥有极大信息量的行业网站门户没有站内全文搜索将会出现怎样的局面&#xff0c;网站全文检索对于挖掘网站信息和整合网站资源…

部署创作的网站元素自定义项

http://technet.microsoft.com/zh-cn/library/cc262041.aspx 更新&#xff1a; 2008-01-17 本文内容&#xff1a; 使用内容部署功能部署内容 使用内容部署包部署内容 使用解决方案包部署内容 本文提供有关使用 Microsoft Office SharePoint Server 2007 部署创作的网站元素…

部署开发的网站元素自定义项

http://technet.microsoft.com/zh-cn/library/cc262995.aspx 更新&#xff1a; 2008-01-17 本文内容&#xff1a; 使用解决方案包部署开发的网站元素 使用功能部署开发的网站元素 本文提供有关使用 Microsoft Office SharePoint Server 2007 部署开发的网站元素自定义项的指…

【软创实验室大作业】学习小组网站

Java部分 封装一个数据结构&#xff0c;这里我选择了双向循环链表&#xff0c;也叫双链表。先简单介绍一下&#xff0c;双向循环链表的每个数据节点都有两个指针&#xff0c;分别指向直接后继和直接前驱。所以&#xff0c;从双向链表的任意一个节点开始&#xff0c;都可以很方…

chatgpt赋能python:Python与SEO的奇妙关系

Python与SEO的奇妙关系 SEO(Search Engine Optimization)&#xff0c;中文翻译为搜索引擎优化&#xff0c;是指通过对网站进行各种技术和内容方面的优化&#xff0c;来提升网站在搜索引擎自然排名中的位置&#xff0c;进而吸引更多的潜在客户。而Python语言&#xff0c;则成为…

chatgpt赋能python:Python一直运行的SEO文章

Python一直运行的SEO文章 介绍 Python是一种高级编程语言&#xff0c;已经流行了近三十年。它拥有简单易读的语法和强大的功能&#xff0c;可以运行在Windows、Linux和MacOS等多个平台上。Python已经成为了Web开发、数据科学、人工智能和网络安全领域的首选语言。 在SEO领域…

chatgpt赋能python:Python开发在SEO的应用

Python 开发在 SEO 的应用 介绍 Python 是一种高级、可解释性、面向对象的编程语言&#xff0c;它具有可扩展性和良好的表示能力。Python 是一种广泛应用于网络开发、科学计算、人工智能、数据分析等领域的语言。Python 已经成为许多 SEO 网站的首选开发语言&#xff0c;因为…

学成在线网站知识分享

学成在线网站知识分享 学成在线网站是一个比较基础的网页布局&#xff0c;让刚刚学习前端的人通过使用工具测量大小&#xff0c;裁剪图片&#xff0c;使用盒子定位布局&#xff0c;利用浮动放置浮动盒子等各种知识点都会使用到。各大教学网站也会使用这个案例来教学基础的布局…

摄影图片分享网站制作

摄影图片分享网站制作 目录 前言 一、首页的制作 二、风景篇和美食篇 三、人物篇和联系我们篇 总结 前言 上一次分享了学成在线网站的制作知识分析&#xff0c;这一次我来分享我制作摄影图片分享网站的制作了。这一次的网页制作需要用到新的东西&#xff0c;让我们一起来看…

Java学习网站推荐

学习Java不仅依靠自身的努力,还要多看一些相关技术文档,那么必不可少的就是学习Java的网站,本人整理收集一些Java学习网站,这些网站可以提供一些最新Java的资料,有时定期开设讲座等线下活动,而且里面的一些Java相关的问题以及讨论,不仅适用于Java小白程序员,而且还适用…

java在线电影网站

Java在线电影网站 项目简介 这次分享一个电影网站&#xff0c;基于JspServletC3p0mysql&#xff0c;难度适中。网站内视频均是跳转到相应的平台播放&#xff08;如腾讯视频、爱奇艺、优酷等&#xff09;&#xff0c;后台管理员可观察在线人数&#xff0c;并添加新的视频&…

Vue入门——我的第一个vue网站

今天我们来谈一谈Vue的相关事宜。 环境的搭建&#xff0c;网上教程很多&#xff0c;而且也很方便&#xff0c;我就不细说了。 然后我们新建一个文件夹作为它的工作环境——workspace。之后控制台进入到这个文件夹里面&#xff0c;然后执行下面代码来创建我的第一个项目。 vu…

预编译解决vue-cli 4.0项目的seo问题

预编译解决vue-cli 4.0项目的seo问题# vue项目上线之后要求解决一下seo问题&#xff0c;现在总结一下 希望能帮到各位 ps&#xff1a;其实网上已经有很多的解释了 我这边就不多做介绍 贴一下vue-cli和依赖的版本 1&#xff0c;需要用到我们的prerender-spa-plugin 和 vue-meta…

前端学习demo网站

https://www.layui.com/demo/progress.html http://semantic-ui.com/