UITableView

来源:互联网 发布:故事树软件 编辑:程序博客网 时间:2024/06/05 18:32

掌握

设置UITableViewdataSourcedelegate

 

UITableView多组数据和单组数据的展示

 

UITableViewCell的常见属性

 

UITableView的性能优化(cell的循环利用)

 

自定义Cell

 

什么是UITableView?

 

能看到各式各样的表格数据就是UITableView

计算机生成了可选文字:什 么 是 UITableView . 在 众 多 移 动 应 用 中 , 能 看 到 各 式 各 样 的 表 格 数 据 拿 收 人 、 为 1 纛 之 , , , 了 以 在 巧 0 “ 上 , , 不 , , 的 籪 . , 代 记 出 , , 这 么 * 蠕 人 , 北 , 小 鬈 , I , 间 0 , “ 人 竇 0 在 i0S 中 , 要 实 现 表 格 数 据 展 亍 , 最 常 用 的 做 法 薪 是 使 用 UlTab1evxew UITab1eViewn 承 自 UIScr011View, 因 此 支 持 垂 直 滚 动 , 而 且 性 能 极 佳

 

计算机生成了可选文字:Ultrableviewstyleplain "e•g-r urrab1eViewsty1eGrouped

 

如何展示数据

UITableView需要一个数据源(dataSource)来显示数据

注意:但是如果删掉原先控制器自动配置的View,用自己定义的UITableView,系统是默认遵守数据源和协议,不用设置!

 

UITableView会向数据源查询一共有多少行数据以及每一行显示什么数据等

 

没有设置数据源的UITableView只是个空壳

 

凡是遵守UITableViewDataSource协议的OC对象,都可以是UITableView的数据源

 

 /**

     *  dataSourceUITableViewDataSource类型,主要为UITableView提供显示用的数据(UITableViewCell),指定UITableViewCell支持的编辑操作类型(insertdeletereordering),并根据用户的操作进行相应的数据更新操作,如果数据没有更具操作进行正确的更新,可能会导致显示异常,甚至crush

    

     delegateUITableViewDelegate类型,主要提供一些可选的方法,用来控制tableView的选择、指定section的头和尾的显示以及协助完成cell的删除和排序等功能。

    

    提到UITableView,就必须的说一说NSIndexPathUITableView声明了一个NSIndexPath的类别,主要用来标识当前cell的在tableView中的位置,该类别有sectionrow两个属性,前者标识当前cell处于第几个section中,后者代表在该section中的第几行。

    

     UITableView只能有一列数据(cell),且只支持纵向滑动,当创建好的tablView第一次显示的时候,我们需要调用其reloadData方法,强制刷新一次,从而使tableView的数据更新到最新状态。

    */

    

 

 

计算机生成了可选文字:tm UI TableViewDataSourc — (NSInteger)number0fSectionsInTableView: (UI TableView — (NSInteger)tableView: (UI TableView numberOfRowsInSection: (NSInteger)section; — (UI TableViewCell (UI TableView cellForRowAtIndexPath: (NSIndexPath indexPath; UlTab1eView eproperty (nonatomic, assign) id CUI TableViewDataSource:• dataSource; it-Fiji* ,

tableView展示数据的过程

调用数据源的下面方法得知一共有多少组数据

-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView;

 

调用数据源的下面方法得知每一组有多少行数据

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section;

 

调用数据源的下面方法得知每一行显示什么内容

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

 

计算机生成了可选文字:V Item 16 V Item O name Item I title Dictionary Dictionary String Strin Dictionary String String String MJCarGroup (2 items) 2 items (2 items) (2 items) NSArray MJCar name — MJCar name -

 

初始MVC

MVC是一种设计思想,贯穿于整个iOS开发中,需要积累一定的项目经验,才能深刻体会其中的含义和好处

 

MVC中的三个角色

MModel,模型数据

VView,视图(界面)

CControl,控制中心

注意:首先控制器会加载这个数据,然后根据这个数据的个数去创建对应的view

 

MVC的几个明显的特征和体现:

View上面显示什么东西,取决于Model

只要Model数据改了,View的显示状态会跟着更改

Control负责初始化Model,并将Model传递给View去解析展示

 

 

Cell简介

UITableView的每一行都是一个UITableViewCell,通过dataSource的tableView:cellForRowAtIndexPath:方法来初始化每一行

 

UITableViewCell内部有个默认的子视图:contentView,contentView是UITableViewCell所显示内容的父视图,可显示一些辅助指示视图

 

辅助指示视图的作用是显示一个表示动作的图标,可以通过设置UITableViewCell的accessoryType(其属性)来显示,默认是UITableViewCellAccessoryNone(不显示辅助指示视图),其他值如下:

UITableViewCellAccessoryDisclosureIndicator

 

UITableViewCellAccessoryDetailDisclosureButton

 

UITableViewCellAccessoryCheckmark (枚举类型)

 

还可以通过cell的accessoryView属性来自定义辅助指示视图(比如往右边放一个开关)

 

注意:这里的cell的指的是通过UITableViewCell创建的一个对象的accessoryView属性来自定义辅助的视图

 

Cell.accessoryView = UITableViewCellAccessoryCheckmark;

 

计算机生成了可选文字:Ul TableViewCellficontentView UlTab1eViewCe11Sty1eDefau1t UlTab1eViewCe11Sty1eSubtit1e UlTab1eViewCe11Sty1eVa1ue1 UlTab1eViewCe11Sty1eVa1ue2 Text Label Text Label Detail Text Label Text Label Detail Text Label Detail Text Label Text Label

 

计算机生成了可选文字:UlTableViewCeıE*ö UIImageView .supcrvıcw UlLabcı .supcrvıcw UlTab1eViewCe11 .imagcVicw .tcxtLabcl .dctailTcxtLabcl .contcntVicw UlLabeı .supcrvıcw Te La ı Detail Text Laöel

 

注意:以上cell的属性包含了4个属性

 

Cell的重用原理

iOS设备的内存有限,如果用UITableView显示成千上万条数据,就需要成千上万个UITableViewCell对象的话,那将会耗尽iOS设备的内存。要解决该问题,需要重用UITableViewCell对象

 

重用原理:当滚动列表时,部分UITableViewCell会移出窗口,UITableView会将窗口外的UITableViewCell放入一个对象池中,等待重用。当UITableView要求dataSource返回UITableViewCell时,dataSource会先查看这个对象池,如果池中有未使用的UITableViewCell,dataSource会用新的数据配置这个UITableViewCell,然后返回给UITableView,重新显示到窗口中,从而避免创建新对象

 

还有一个非常重要的问题:有时候需要自定义UITableViewCell(用一个子类继承UITableViewCell),而且每一行用的不一定是同一种UITableViewCell,所以一个UITableView可能拥有不同类型的UITableViewCell,对象池中也会有很多不同类型的UITableViewCell,那么UITableView在重用UITableViewCell时可能会得到错误类型的UITableViewCell

 

解决方案:UITableViewCell有个NSString*reuseIdentifier属性,可以在初始化UITableViewCell的时候传入一个特定的字符串标识来设置reuseIdentifier(一般用UITableViewCell的类名)。当UITableView要求dataSource返回UITableViewCell时,先通过一个字符串标识到对象池中查找对应类型的UITableViewCell对象,如果有,就重用,如果没有,就传入这个字符串标识来初始化一个UITableViewCell对象

 

Cell的重用代码

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

 

注意:重用机制是根据相同的标识符来重用cell,标识符不同的cell不能彼此重用

 // 1.定义一个cell的标识为ID

     static NSString *ID =@"mjcell";

   

   // 2.从缓存池中取出cell

      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ID];

   

   // 3.如果缓存池中没有cell

     if (cell == nil) {

        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitlereuseIdentifier:ID];

   }

   

   // 4.设置cell的属性...

   

     return cell;

}

 

方法2:注册

                                   

         另一中性能优化的写法:

          0.先确定cell的重用标识

          1.注册带重用标识的cell

          2.从缓存池中取是否有带重用标识的cell(如果没有,系统会根据注册自动创建一个相应的cell返回给我们)

          3.覆盖cell上面的数据

         说明:cell离开屏幕的时候,就会放到tableView的缓存池中,这时候缓存池才有数据

        

   

            3.0 先确定cell的重用标识:命名规范:cell类型+ID

           static NSString *ID =@"carID";// static修饰局部变量,局部变量从执行后始终存在,但不能被其它函数使用,当再次进入该函数时,将保存上次的结果。其它与局部变量一样。

           

           static BOOL isReged = NO;

            3.1 先注册带IDcell

           if (isReged == NO) {

#warning registerCell需要注意的3,面试可能会问到

                   改方法是伴随着UICollectionView出现的,也就是iOS6出现的

                   采用注册创建出来的cell,默认是Default样式,所以一般注册大部分都用在自定义cell的时候

                   需要注意的是[tableView registerNib:<#(UINib *)#>forCellReuseIdentifier:<#(NSString *)#>]iOS5出现的

                   编码规范:xib自定义cell一般用注册

                   [tableViewregisterClass:[UITableViewCell class] forCellReuseIdentifier:ID];

                   isReged =YES;

                  

               }

           

           // 3.2 查看缓存池中是否有带重用标识的cell

           // 缓存池方法中封装了,如果缓存池中没有,就根据注册创建新的cell,然后返回给我们一个带IDcell

           UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:ID];

           

           // 3.3 覆盖cell上的数据

           XMGCar *car =self.cars[indexPath.row];

           

           cell.textLabel.text = [NSString...

                                                               

             // 3.4返回cell

           return cell;

                                                               }

 

 

 

                          

#方法3:storyboard

                             

                            

      

                 另一中性能优化的写法(storyboard):

                 

                  0.先确定cell的重用标识

                  1.storyboard中的tableView中的cell的重用标志赋值

                  2.从缓存池中取是否有带重用标识的cell

                  (2.1如果没有,系统会根据注册自动创建一个相应的cell返回给我们;

                  2.2如果也没有注册过,系统会根据storyboard中写好的带重用标志的cell来自动创建,然后返回)

                  3.覆盖cell上面的数据

                 说明:cell离开屏幕的时候,就会放到tableView的缓存池中,这时候缓存池才有数据

 

 3.返回每行内容:该方法,只有当cell显示在屏幕上的时候才会调用,是一种懒加载的思想

                             

#warning如果有注册,就不会触发storyboard的创建新cell的机制.只有没有注册过,并且storyboard中没有标记相应cell的时候,dequeueReusableCellWithIdentifier才会返回nil

                             - (UITableViewCell *)tableView:(UITableView *)tableViewcellForRowAtIndexPath:(NSIndexPath *)indexPath

       {

                3.0 先确定cell的重用标识:命名规范:数据的模型+ID

              static NSString *ID=@"carID"; static修饰局部变量,局部变量只会分配一次内存地址

               

               

                3.1 查看缓存池中是否有带重用标识的cell

                缓存池方法中封装了,如果缓存池中没有,就根据注册创建新的cell,然后返回给我们一个带IDcell

                后面还封装了一层,如果也没有注册呢,会根据storyboard中是否标记了在重用cell,来创建一个新的cell然后返回

               UITableViewCell *cell = [tableViewdequeueReusableCellWithIdentifier:ID];

               

               

                3.3 覆盖cell上的数据

               XMGCar *car =self.cars[indexPath.row];

               cell.textLabel.text = [N...

                                                                      

                                                                     

                                                                     return cell;

                                                                      }

                                                                     

 

 

 

 

 

     3.修改控件属性(一半在cell的创建方法中设置initWithStyle)

    cell.imageView.layer.cornerRadius = 22;  设置圆角为正方形边长一半(内切圆半径)

    cell.imageView.layer.masksToBounds = YES;设置将位于imageView之下的layer都遮盖住(默认是NO) 等效代码是:cell.imageView.clipsToBounds

    

    //设置字体以及文字颜色

    cell.textLabel.textColor = [UIColorbrownColor];

    cell.detailTextLabel.font = [UIFontsystemFontOfSize:12.0];

    cell.detailTextLabel.textColor = [UIColorgrayColor];

    

    //设置辅助视图

    cell.accessoryType =UITableViewCellAccessoryDetailButton;

 

 

使用xib封装一个view的步骤

新建一个xib文件描述一个view的内部结构(假设叫做MJTgCell.xib)

 

新建一个自定义的类

(自定义类需要继承自系统自带的view,继承自哪个类, 取决于xib根对象的Class)

 

新建类的类名最好跟xib的文件名保持一致(比如类名就叫做MJTgCell)

 

xib中的控件 和 自定义类的.m文件 进行连线

 

提供一个类方法返回一个创建好的自定义view(屏蔽从xib加载的过程)

 

提供一个模型属性让外界传递模型数据

 

重写模型属性的setter方法,在这里将模型数据展示到对应的子控件上面

 

Delegate的使用场合

对象A内部发生了一些事情,想通知对象B

 

对象B想监听对象A内部发生了什么事情

 

对象A想在自己的方法内部调用对象B的某个方法,并且对象A不能对对象B有耦合依赖

 

对象A想传递数据给对象B

 

……

 

以上情况,结果都一样:对象B对象A的代理(delegate)

 

使用delegate的步骤

先搞清楚谁是谁的代理(delegate)

 

定义代理协议,协议名称的命名规范:控件类名 + Delegate

 

定义代理方法

代理方法一般都定义为@optional

代理方法名都以控件名开头

代理方法至少有1个参数,将控件本身传递出去

 

设置代理(delegate)对象 (比如myView.delegate = xxxx;)

代理对象遵守协议

代理对象实现协议里面该实现的方法

 

在恰当的时刻调用代理对象(delegate)的代理方法,通知代理发生了什么事情

(在调用之前判断代理是否实现了该代理方法)

 

通过代码自定义cell(cell的高度不一致)

1.新建一个继承自UITableViewCell的类

注意:一个是初始化方法一个设置子控件的方法一个是设置数据的对象的set方法

 

2.重写initWithStyle:reuseIdentifier:方法

添加所有需要显示的子控件(不需要设置子控件的数据和frame,  子控件要添加到contentView

进行子控件一次性的属性设置(有些属性只需要设置一次,比如字体\固定的图片等等但是设置frame不行)

 

3.提供2个模型

数据模型:存放文字数据\图片数据 (字典转模)

frame模型:存放数据模型\所有子控件的frame\cell的高度

 

4.cell拥有一个frame模型(不要直接拥有数据模型)

 

5.重写frame模型属性的setter方法:在这个方法中设置子控件的显示数据和frame

 

6.frame模型数据的初始化已经采取懒加载的方式(每一个cell对应的frame模型数据只加载一次)

 

UITextField

通过UITextField的代理方法能够监听键盘最右下角按钮的点击

成为UITextField的代理

self.textField.delegate =self;

 

遵守UITextFieldDelegate协议,实现代理方法

-(BOOL)textFieldShouldReturn:(UITextField *)textField;

 

 

UITextField左边放一个view

self.textField.leftView = [[UIViewalloc] initWithFrame:CGRectMake(0,0, 8, 0)];

self.textField.leftViewMode =UITextFieldViewModeAlways;

 

***************************笔记************************

********************************************************

   修改cell的高度,也就是行高

    self.tableView.rowHeight = 60;

    

     修改组头.组尾的高度(Plain样式下生效):Group样式下,组头组尾高度都是系统默认的

    self.tableView.sectionHeaderHeight = 2;

    self.tableView.sectionFooterHeight = 222;

    

     设置tableView的表头表尾视图

     一般用于做下拉刷新,banner

    self.tableView.tableHeaderView = [UIButtonbuttonWithType:UIButtonTypeContactAdd];

    self.tableView.tableFooterView = [[UISwitchalloc] init];

    

     设置分割线颜色:

     [UIColor clearColor]如果设置成透明色就表示分割线取消显示

#warningtableView,尽量避免使用透明色

    self.tableView.separatorColor = [UIColororangeColor];

    

     UITableViewCellSeparatorStyleNone取消分割线的显示

#warningUITableViewCellSeparatorStyleNone->UITableViewCellSelectionStyleNone

    self.tableView.separatorStyle =UITableViewCellSeparatorStyleNone;

 

 隐藏状态栏

- (BOOL)prefersStatusBarHidden

{

    return YES;

}

 

     设置cell的属性

     设置cell的背景颜色 backgroundColor优先级低于backgroundView

    cell.backgroundColor = [UIColorcolorWithRed:arc4random_uniform(255)/255.0green:arc4random_uniform(255)/255.0blue:arc4random_uniform(255)/255.0alpha:1];

    

    UIView *bg = [[UIView alloc] init];

    bg.backgroundColor = [UIColorgrayColor];

    cell.backgroundView= bg; 一般用于UIIMageView展示公司logo

    

    

      

 

        typedef NS_ENUM(NSInteger, UITableViewCellAccessoryType) {

    UITableViewCellAccessoryNone,                  don't show anyaccessory view 默认没有

 

   UITableViewCellAccessoryDisclosureIndicator,    regular chevron. doesn't track尖尖

    

UITableViewCellAccessoryDetailDisclosureButton, info button w/ chevron. tracks! +尖尖

  

UITableViewCellAccessoryCheckmark,             checkmark. doesn't track 对号

 

   UITableViewCellAccessoryDetailButton NS_ENUM_AVAILABLE_IOS(7_0)// info button. tracks  !

       

     设置辅助视图

     accessoryView优先级高

    NSUInteger row = arc4random_uniform(255);

    if (row % 2) {

        cell.accessoryView = [[UISwitchalloc] init];

    }else

    {

        cell.accessoryType =UITableViewCellAccessoryDetailDisclosureButton;

    }

0 0
原创粉丝点击