一、今天呢,我们就来学习这个自定义Cell, 1.通过这两个案例掌握自定义Cell的使用 2.下面这个完全“手写代码”实现自定义Cell, 什么意思呢, 就是完全自己写一个类,继承自UITableViewCell这个类, 通过代码的方式来实现自定义Cell, 3.上面这是通过xib的方式,实现自定义Cell, 4.作业,就是把今天的案例,每个都写一遍,如果你觉得写的不熟的话,那就每个都写两遍, 二、那么,在我们开始之前,先介绍按照MVC的方式,来组织项目结构 1.团购案例,就是我们这里看到的这个东西, 2.首先,上面,就是我们上次做的那个图片轮播器吧, 然后,下面这个是个UITableView, 3.然后,最下面,有一个“加载更多”, 当我点这个加载更多的时候,显示“拼命加载”, 等会儿,又加载出来了一条儿, 3.上面这个图片轮播器,和下面的加载更多,属不属于UITableView里面的控件, 再想想UIScrollView,当你把控件放到UIScrollView里面,当UIScrollView滚动的时候,里面的控件,会随着它滚动吗,会随着它滚动吧, 这里,所有的控件是不是都会随着UITableView一起滚, 证明这些控件都是在UITableView里面的, 4.上面这一部分, 这是UITableView的一个TableHeaderView, 就是头部,headerView里面显示的内容, 4.那么我们,下面这个“加载更多”,是UITableView的footerView里面显示的, 所有我们上、下,有这么两部分,这两部分都是属于UITableView的, 并且,上面是在一个headerView里面,下面是在一个footerView里面, 5.下面,介绍一下按照MVC的方式来组织项目结构, 5.然后,在介绍一下UITableViewController, 二、来实现一下这个团购案例, 1.你现在就想一下,我下面该怎么做, 1)我一会儿肯定会拽一个UITableView上来, 2)然后,设置数据源对象, 3)然后,懒加载,建模型, 是不是这些是肯定的啊, 2.咱们控制器的View,还是用3.5英寸,模拟器还是用iPhone4S, 3.新建一个项目,叫做001团购案例, 首先,我把这个项目,起一个前缀, Class Prefix:CZ, 这样的话,我们后面新建的类,都是以CZ开头的, 虽然模拟器是iPhone4S,但是操作系统还是iOS8,因为我这里的Deployment Target:iOS 8.1 表示,最低运行,是在iOS8.1下吧, 当然,模拟器你可以选运行哪个操作系统,模拟器可以选, 4.然后,我们调完控制器,调完模拟器之后,我们要把素材拷进来, 图片效果,需要把图片拷进来,然后数据,来源于一个plist文件吧, 图片素材,就拽到这个Images.xcassets文件夹下, tgs.plist文件,就拽到这个Supporting Files文件夹下, 5.懒加载数据的时候,是从我们这个plist文件中加载,所以我们先打开这个文件,那么打开这个文件,一下看到了这么多字典,肯定想到了要干什么, 肯定要字典转模型啊,整体是一个Array,所以整体是要放到一个数组里面啊, 然后呢,我们观察一下,每一个字典里面有几个键值对, 是不是4个, 1)buyCount是购买数量,我们看一下, 这个“正院大宅门”,几个人购买,“1 人已购买”吧, 所以这个buyCount就是1吧, 2)这个icon,就是我们当前这个商品对应的图片, 3)这个price,就是指当前那个商品的价格, 4)这个title,就是指当前这个商品的名称,这个标题, 所以,我们第一步,就要先建一个模型, 用一个模型,来描述这一个字典对象, 我们这里为了使用方便,把键值对的数据类型,都设置为String类型, 这样的话,等会儿咱们写起来方便,仅此而已, 事实上,你真正在开发的时候,有可能这个地方不是String吧, 是非常有可能的,我们对我们这里如果要计算,就要用数字类型,如果不计算,就用String,是没有问题的, 展示的时候,最终都是字符串,在服务器的数据库里存的时候,是数字类型, 5.这里呢,我们先建一个模型,建模型之前,我们就先说一下我们MVC分文件夹的方式来存储, 1)Models:用来存储模型类,用来存储数据的, 2)Views:用来存储视图,用来展示数据的控件, 3)Controllers:用来创建模型,创建View的一个控制器, 我们可以把项目中的某一部分,按MVC方式这么分, 整个项目,可以有很多很多个MVC这样的组合, 组合起来以后,就是一个更大的项目了, 就好比说,项目中的某一部分,比如说,图片轮播器, 它内部分了MVC,三部分, 整体这个项目,又分了比如说好多个图片的模型, 是不是好多组的MVC, 又组成了一个整体的一个大的一个MVC吧, Model,用来存储数据,View,用来展示数据,Controller,用来对模型,和控件,和View的一个组合, 选中这个文件夹,右键,选择New Group, 这个Group,并不是保存在磁盘上的文件夹,它只是逻辑上的这么一个结构,这么一个节点, 1)第一个,叫做Models,保存所有的模型, 2)第二个,叫做Views,保存所有的控件, 我们所有的控件,都是继承自UIView的, 3)第三个,叫做Controllers,保存所有的控制器, 这个AppDelegate,不属于MVC中的任何一部分, 4)第四个,建一个Others,保存其他的一些内容, 1)AppDelegate.h、AppDelegate.m,这两个,属于应用程序代理的一部分,拖到Others里面, 2)ViewController.h、ViewController.m,这两个,属于控制器,拖到Controllers里面, 3)Main.storyboard,LaunchScreen.xib,这两个,属于描述软件界面的,拖到Views里面, 4)Images.xcassets,这个是保存资源图片的,拖到Supporting Files里面, 它就属于所有我们项目的其他一些支持文件, 比如说,项目里面的声音文件,图片文件,都可以放到这个Supporting Files里面, 这样我们就分好了组, 我们在Finder中打开这个文件夹,发现并没有这么多文件夹, 既然我们这里没有这么多文件夹,也就意味着,我们的应用程序安装到手机上以后,还是安装到了NSBundle mainBundle,这个根目录下面了啊, 如果说,你这里建了个文件夹,建了个“a”这个文件夹, 然后呢,比如说,你把这个tgs.plist文件,放到这个“a”这个文件夹下了,因为这里确实有一个文件夹,所以说,你在代码中,再加载这个plist文件的时候,就不能直接从NSBundle mainBundle根目录下加载了,就得从根目录下的“a”目录下找这个文件, 所以说,我们这里的Group,只是一个逻辑上的Group,并没有真正产生这个文件夹,所以说,我们后面加载这个plist文件的时候,仍然可以从根目录下加载, 三、懒加载数据, 1.需要建一个模型类,这个模型类有四个属性, 这个模型类,建在Models这个Group下吧, 大家,可以选择OS X下面的这个Source来建,也可以选择iOS下的这个Source来建, 但是推荐你,还是选择上面这个来建,因为我们现在做的是iOS开发,不是做的OS X开发吧, 你选上面这个,它会有一些比较好的自动生成的代码,但是如果选择下面这个的话,它就不会给你生成这些iOS代码, 2.我们这个是一个模型类,注意,我们这个模型是用来描述一个什么,商品吧, 所以商品,可以给它起名叫Goods,之类的, CZGoods, 3.这个模型里面,包含四个属性, 1)buyCount, 2)icon, 3)price, 4)title, 4.实现那两个方法, 实现这两个方法, 5.然后开始懒加载数据, 在哪里写代码,在控制器里写代码, 先在控制器的ViewController.m文件里面,建一个属性,用来保存懒加载起来的数据, 懒加载数据, 如果在控制器的ViewController.m文件里面,访问不到CZGoods类,别忘了在ViewController.m文件最前面,引入头文件, #import “CZGoods.h“ 7.然后,拽一个UITableView上来, 然后,设置它的数据源对象, 然后,控制器遵守UITableView的数据源协议, 实现三个数据源方法, 1)返回多少组, 2)每组返回多少行, 3)每一组每一行返回什么样的单元格, 然后,第三个数据源方法,就是,每一组每一行返回什么样的单元格, 注意,只要是在这个方法中,就是四部, 1)获取模型数据, 2)创建单元格, 3)把模型数据设置给单元格, 4)返回单元格, 1)获取模型数据, CZGoods *model = self.goods[indexPath.row]; 2)创建单元格,对单元格进行重用,先定义一个重用ID,然后去缓存中取,取不到以后,你再创建, static NSString *ID = @“goods_cell”; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID]; if(!cell){ cell = [UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:ID]; } 3)把模型里面的数据设置给单元格, 注意,需要拼接字符串,显示价格,因为前面有个人民币符号, 按理说,这样就完了,但是我们模型里,还有一个值,是buyCount,已购买人数, 这个“已购买人数”,怎么办, 这里没有第四个控件了,如果你非要实现这个效果的话,是不是只能在这里进行拼接了, 4)最后,直接把这个单元格返回, return cell; 运行一下看看, 来,看一下,这个数据是不是有了, 8.接下来,把状态栏隐藏, - (BOOL)prefersStatusBarHidden{ return YES; } 注意看,我们现在状态栏是不是没有了吧,但是多少人已购买,因为字符串的长度不一样,是不是根本没有对齐啊, 文字颜色也不一样吧,示例程序的文字是橘黄色和灰色的, 也就是说,这个橘黄色的价格,和后面这个灰色的已购买人数,不能在一个Label上实现吧,如果要在一个Label上实现,将会非常复杂, 也就是说,我们写代码的时候,用系统自带的这个单元格,功能不够了吧, 接下来,我们只能自定义单元格了,