文档章节

关于UITableView你知道多少——UITableView简单解析

浪子艾菲儿
 浪子艾菲儿
发布于 2013/08/07 12:52
字数 1865
阅读 1548
收藏 9

转自萧宸宇的博客 

UITableView是在iOS开发中,展示大量内容的首选。我个人认为的原因有以下几点:

1.UITableView的展现形式是为移动设备专门设计过的。有较好的人机交互体验。

2.从技术角度来说UITableView具有重用和延迟加载等特性。如果使用恰当。可以获得一个App流畅的用户体验。

 

这样,使得UITableView在iOS App中随处可见。

 

原生应用

一些有名的App.图片信息较老

包括游戏

这些都说明UITableView在一个App中其实是一个很常用的控件。我应该好好的学习它。

 

关于数据的思考

没有UITableView的时候我是这样想的

首先思考为什么会有UITableView这样的控件。我们做一个App的时候,就会有大量的数据需要显示。比如weibo的每一个状态。比如一个新闻App的很多条新闻。这些数据都会有一个特点就是他们的组织形式一样,只是内容变化。有时候我们可能会根据一些条件进行分组。使得看来了是分组的。例如 联系人里面会按照首字母来进行分组一样。我们还可能会点击数据以便查看更详细的内容。

 

通过上面的简单描述,如果来自己实现一个类似UITableView的结构。需要得到最核心的:

1.需要得到一共多少条数据

2.数据的具体内容是什么

 

如果我们数据需要更加仔细的描述展示:

1.全部的数据一共有多少组

2.每一组有多少个数据

3.每一条数据的具体内容是什么

 

UITableView是怎么做的

在UITableView中。最重要的就是data source中的两个方法。

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

 

什么是data source。字面意思就是很明白,数据的来源。一般情况下我们会设置拥有UITableView的这个UIViewController为他的data source。因为根据MVC来说。

 

UITableView是View,UIViewController是Controller。View需要的数据,应该是Controller去跟Model协调然后获得,以后由Controller去给View来进行显示。View永远的不去直接跟Model联系。这样当UITableView初始化的时候。他就会去问他的data source。我需要显示多少行数据啊。每一行的数据都是什么内容啊。这时候UIViewController应该已经从Model拿到了数据。然后通过- (NSInteger)tableView:(UITableView )tableView numberOfRowsInSection:(NSInteger)section;告诉UITableview,恩你的这一组要显示n条数据。又用- (UITableViewCell )tableView:(UITableView )tableView cellForRowAtIndexPath:(NSIndexPath )indexPath函数告诉UITableView说,第几组第几条数据的具体内容是什么。

 

UITableView还有一个比较犀利的地方就是如果你的数据有10000条。它肯定不是把10000条都加载进来。而是只加载需要显示的条目数据。这样设计,使得UITableView的流畅程度大大提高。值得注意的是,如果Cell里面的数据是从网络 or Core Data等其他地方读取的。我们应该把读取动作写成异步的。不阻塞主线程。取到数据以后在回答主线程去刷新UI。

 

UITableView从创建到显示的调用顺序如下图

(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView这个函数是最先调用,但是它默认返回1.所以并不是必须的。如果你的UITableView分了好几组,这个就是用来返回组的数量的。

这样完成了设置UITableView的data source设置。再完成

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

 

这两个函数。我们就可以得到一个能显示的UITableView了。

 

现在是是仅仅解释了UITableView的数据是怎么来的,然后怎么对应到UITableView上面。

 

UITableViewCell

UITableViewCell具体的每一条数据展示的具体View。首先在UITableView里面有这样一个特点,每一个Cell的大概样子都长的差不多,只是里面具体的内容稍有变化。这样在UI里面我们应该是重用相同的部分,改变不同的部分。这样才能提高效率。因为在UiTableView这个视图里面,用户习惯性快速的滚动,视图和数据内容都会快速的变化,如果效率问题处理不好,很容易有卡顿的现象。造成用户体验的降低。

 

如果使用默认的UITableViewCell风格,有以下四种:

UITableViewCellStyleDefault

UITableViewCellStyleSubtile

UITableViewCellStyleValue1

UITableViewCellStyleValue2

当然如果是需要自定义Cell也是很简单。 用xib拖一个,完全可以GUI的方式来创建,很是方便。

 

(Google一个栗子吧,写不动了)插一句,Cell的重用是需要下面这样的实现方法

  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath  {      static NSString *Cell = @"MyCell";      UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:Cell];      if (!cell) {          cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:Cell];      }      return cell;  }

重要的是UITableView的dequeueReusableCellWithIdentifier方法。

 

dequeueReusableCellWithIdentifier去一个队列里面需找有没有相同ID的的Cell。如果有就提出来重用。可以重用的部分。如果没有就跳进if里面去创建。所以我们在if里面创建的时候,不会改变的内容都可以在里面创建,这样就只用创建一次。需要改变的内容我们就放到if后面去写。 这样我们就能完成高效的UITableView。当然,理论上来说,你可以不用这样的机制,而去直接每次创建一个Cell。不过这是非常浪费资源的一个做法,直接不提倡。

 

UITableView Delegate

当然,在写UITableView肯定想控制的更多。才能完成设计师们辛辛苦苦画出来的稿。这样我们可以去看看Data source里面剩下的函数和Delegate。当然就说一点

 

  //选中Cell响应事件  - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath  {      //选中后的反显颜色即刻消失      [tableView deselectRowAtIndexPath:indexPath animated:YES];  }

 

这个是选中Cell时候会的出发点。如果要点击以后做什么事情 就在这里做了。

 

找了篇目测还ok的  中文blog可以先看看了解 

 

数据刷新

如果我们的modle更新了。相应的要体现到UITableView上面。简单的我们可以reload整个TableView。这样做很方便,而且数据上没有问题。唯一的问题就是,reload整个TableView的效率太低了。而且,往往我们只是少数的Cell内容变化。所以没有必要去reload整个TableView。而是那条数据变化去刷新对应的Cell就好了。这样做效率提高很多。

 

具体涉及到的几个函数

  - (void)beginUpdates;  - (void)endUpdates;     - (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;  - (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;  - (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;     - (void)insertRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation;  - (void)deleteRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation: (UITableViewRowAnimation)animation;  - (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;

这里有实例代码可以参考

 

苹果官方教程

 

里面写了如何优化UITableView:

 

又找了一篇blog写的很不错的样子,  优化UITableView性能

 

后记

总结就是UITableView是一个高度设计的控件。它具有重用,分组,异步加载数据等方面需要我们注意。

 

其实这里插进来写UITableView是为了写NSFetchedResultsController。因为NSFetchedResultsController就是为UITableview量身打造的Core Data的类。

 

所以,先说明以下UITableView,然后再写NSFetchedResultsController。

本文转载自:

浪子艾菲儿
粉丝 45
博文 49
码字总数 13001
作品 0
海淀
程序员
私信 提问
UITableView的优化原理

当我们下啦一个 UITableView时,如果没有做优化,只是简单的实现功能代码如下,这样当我们有上百条tableviewcell的时候,我们滑动的非常快时会非常费内存,当然苹果公司不会让我们这样干,苹...

哥特复心
2013/11/29
5.3K
3
iOS UITableView代理方法详解

iOS UITableView的代理方法详解 一、补充 在上一篇博客中,http://my.oschina.net/u/2340880/blog/404605,我将IOS中tableView(表视图)的一些常用方法总结了一下,这篇将tableView的代理方法...

珲少
2015/04/22
671
2
关于UITableViewCell和UITableView之间的消息传递

问题:当UITableViewCell中发生点击事件(或者其他事件)时,它是如何通知UITableView然后调用UITableView的delegate呢? 详细描述:UITableViewCell中没有属性可以设置它所在的UITableView...

罗包子
2015/04/13
325
0
UITableView 基本使用方法总结

首先,Controller需要实现两个 delegate ,分别是 UITableViewDelegate 和 UITableViewDataSource 2.然后 UITableView对象的 delegate要设置为 self。 3. 然后就可以实现这些delegate的一些方...

悠哉悠哉e
2012/11/13
762
0
UITableView 一些方法

1. UITableView的初始化 [csharp] view plain copy UITableView tableview= [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 420)]; [tableview setDelegate:self]; [tableview s......

晨曦之光
2012/05/16
866
0

没有更多内容

加载失败,请刷新页面

加载更多

【JVM学习】2.Java虚拟机运行时数据区

来源: 公众号: 猿人谷 这里我们先说句题外话,相信大家在面试中经常被问到介绍Java内存模型,我在面试别人时也会经常问这个问题。但是,往往都会令我比较尴尬,我还话音未落,面试者就会“...

物种起源-达尔文
18分钟前
2
0
dart datetime

var date = DateTime.now().toUtc(); //格式化输出 String timestamp = "${date.year.toString()}-${date.month.toString().padLeft(2, '0')}-${date.day.toString().padLeft(2, ......

zdglf
56分钟前
20
0
如何在Linux中复制文档

在办公室里复印文档过去需要专门的员工与机器。如今,复制是电脑用户无需多加思考的任务。在电脑里复制数据是如此微不足道的事,以致于你还没有意识到复制就发生了,例如当拖动文档到外部硬盘...

老孟的Linux私房菜
今天
47
0
SpringBoot 集成MongoDB

一、MongoDB 简介 MongoDB 如今是最流行的 NoSQL 数据库,被广泛应用于各行各业中,很多创业公司数据库选型就直接使用了 MongoDB,但对于大部分公司,使用 MongoDB 的场景是做大规模数据查询...

zw965
今天
49
0
使用 Envoy 和 AdGuard Home 阻挡烦人的广告

> 原文链接:使用 Envoy 和 AdGuard Home 阻挡烦人的广告 通常我们使用网络时,宽带运营商会为我们分配一个 DNS 服务器。这个 DNS 通常是最快的,距离最近的服务器,但会有很多问题,比如: ...

米开朗基杨
今天
48
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部