uitableviewcell xib滚动卡顿,有image原因,求解答

常规配置如下 当超过tableView显示的范围的时候 后面显示的内容将会和前面重复
// 这样配置的话超过页面显示的内容会重复出现
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
// 定义唯一标识
static NSString *CellIdentifier = @&Cell&;
// 通过唯一标识创建cell实例
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// 判断为空进行初始化
--(当拉动页面显示超过主页面内容的时候就会重用之前的cell,而不会再次初始化)
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
// 对cell 进行简单地数据配置
cell.textLabel.text = @&text&;
cell.detailTextLabel.text = @&text&;
cell.imageView.image = [UIImage imageNamed:@&4.png&];
//通过以下3方案可以解决
方案一 &取消cell的重用机制,通过indexPath来创建cell 将可以解决重复显示问题 不过这样做相对于大数据来说内存就比较吃紧了
通过不让他重用cell 来解决重复显示
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
// 定义唯一标识
static NSString *CellIdentifier = @&Cell&;
// 通过indexPath创建cell实例 每一个cell都是单独的
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
// 判断为空进行初始化
--(当拉动页面显示超过主页面内容的时候就会重用之前的cell,而不会再次初始化)
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
// 对cell 进行简单地数据配置
cell.textLabel.text = @&text&;
cell.detailTextLabel.text = @&text&;
cell.imageView.image = [UIImage imageNamed:@&4.png&];
方案二 &让每个cell都拥有一个对应的标识 这样做也会让cell无法重用 所以也就不会是重复显示了 显示内容比较多时内存占用也是比较多的和方案一类似
同样通过不让他重用cell 来解决重复显示 不同的是每个cell对应一个标识
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
// 定义cell标识
每个cell对应一个自己的标识
NSString *CellIdentifier = [NSString stringWithFormat:@&cell%ld%ld&,indexPath.section,indexPath.row];
// 通过不同标识创建cell实例
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// 判断为空进行初始化
--(当拉动页面显示超过主页面内容的时候就会重用之前的cell,而不会再次初始化)
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
// 对cell 进行简单地数据配置
cell.textLabel.text = @&text&;
cell.detailTextLabel.text = @&text&;
cell.imageView.image = [UIImage imageNamed:@&4.png&];
方案三 只要最后一个显示的cell内容不为空,然后把它的子视图全部删除,等同于把这个cell单独出来了 然后跟新数据就可以解决重复显示
当页面拉动需要显示新数据的时候,把最后一个cell进行删除 就有可以自定义cell 此方案即可避免重复显示,又重用了cell相对内存管理来说是最好的方案 前两者相对比较消耗内存
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
// 定义唯一标识
static NSString *CellIdentifier = @&Cell&;
// 通过唯一标识创建cell实例
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// 判断为空进行初始化
--(当拉动页面显示超过主页面内容的时候就会重用之前的cell,而不会再次初始化)
if (!cell) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
else//当页面拉动的时候 当cell存在并且最后一个存在 把它进行删除就出来一个独特的cell我们在进行数据配置即可避免
while ([cell.contentView.subviews lastObject] != nil) {
[(UIView *)[cell.contentView.subviews lastObject] removeFromSuperview];
// 对cell 进行简单地数据配置
cell.textLabel.text = @&text&;
cell.detailTextLabel.text = @&text&;
cell.imageView.image = [UIImage imageNamed:@&4.png&];
以上都是个人理解,本人也是菜鸟,有理解不对的地方希望大家指出,同时也希望能对大家起到一定的帮助!! Thank you!图文混排的贴子回复列表,适合用 UITableView 吗?图片异步加载后需要重新计算行高后如何重新渲染 UITableViewCell - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
已注册用户请 &
iOS 开发实用技术导航
NSHipster 中文版
cocos2d 开源 2D 游戏引擎
Google Analytics for Mobile 统计解决方案
Design Guides and Resources
Transcripts of WWDC sessions
Cocoa with Love
Cocoa Dev Central
iOS 开发实用书单
Style Guides
Useful Tools and Services
图文混排的贴子回复列表,适合用 UITableView 吗?图片异步加载后需要重新计算行高后如何重新渲染 UITableViewCell
23:45:13 +08:00 · 5009 次点击
最近在用 DTAttributedTextContentView () 做图文混排,图片都是 lazy load 的,图片加载完成后,有个回调方法 - (void)lazyImageView:(DTLazyImageView *)lazyImageView didChangeImageSize:(CGSize)size ,这里可以获得图片的高度,或者重新计算 DTAttributedTextContentView 的高度。
那么问题来了,图片加载后 DTAttributedTextContentView 的高度肯定会增加,这个 DTAttributedTextContentView 是在一个 UITableViewCell 里的,如何对它重绘?如果调用
[tableview reloadRowsAtIndexPaths:[NSArray arrayWithObject: xxxIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic]
这个方法,这个 cell 还是会被重新加载,高度还是重新计算,成为一个死循环。
我在做的是 iOS8 only app, TableViewCell 用的是约束布局。 似乎调用 [cell setNeedsDisplay] 也是没效果的
第 1 条附言 &·&
19:42:07 +08:00
@ @ @ @ @ @ @ 我简单看了下了目前两个论坛客户端:威锋 和 NGA: 
这两个客户端都是传统的论坛,我抓包看过了,没有理想的带图片大小的 API。而且都是一个占位符(跟要加载的图片大小无关,就是为了表示这个位置会加载一个图片,图片加载完成后会调整)。但是情况远远没有各位想象的糟糕,因为如果某个贴子楼层已经拉到了屏幕上面,这个图片即使加载完成也不会显示(导致“蹦来蹦去”)。
43 回复 &| &直到
09:13:06 +08:00
& & 23:48:37 +08:00
一直想问问,为啥ios开发和安卓开发里面的内置类或对象,都是驼峰命名?没有下划线命名吗?
& & 00:11:07 +08:00 via iPhone
圖片固定比例是 UI 設計的常識吧...
& & 00:53:41 +08:00 via iPhone
问题是 V2EX 的图片附件这样的
& & 01:37:26 +08:00
不如固定显示成缩略图小正方形,提供一个点击查看大图的功能……?
& & 03:46:19 +08:00
你應該改變設計讓圖片的大小變成固定的,或者顯示多行圖像,但是每行的行高是固定的。
即使 UITableView 能如你所說實現根據異步加載的內容動態調整尺寸,其所帶來的跳躍也是相當不友好的,尤其是在滾動中,用戶滾着滾着就丟失目前滾到哪的感知了。
& & 08:08:22 +08:00 via iPhone
说下场景,就是 V2EX 客户端,帖子回复里的图片数量,大小和比例都不确定。如果缩略图固定比例肯定会非常难看,还是有必要动态调整的。
目前这么做(动态调整)的就是威锋网客户端,但是不知道它是怎么实现的。
能否简单介绍下思路?谢谢!
& & 08:10:22 +08:00
好一個 &肯定會&...
& & 08:23:10 +08:00 via iPad
@ 接口中返回图片的高宽,本地计算合适的size,布局的时候直接用size。
& & 08:26:57 +08:00 via iPhone
@ V2EX 没有这样的接口啊
& & 08:30:12 +08:00 via iPhone
您如果觉得我这个“肯定会”有问题请说原因。
假如图片比例是 3:2 ,变成 1:1 必然不好看吧。
& & 08:36:36 +08:00
1.接口返回图片宽高,事先占位
2.固定图片宽高
& & 08:58:21 +08:00 via Android
不需要,直接修改height delegat然后
tableview.benginupdate
tableview.endupdate
& & 09:00:34 +08:00 via Android
如果你使用的autolayout让iOS自己计算的话,用constraint把内容撑大就好了。
& & 09:21:17 +08:00
@ 歪楼好惨,iOS 除非特殊情况没有下划线命名,因为 SDK 就是这么做的,为了写人能看懂的代码,跟着 SDK 走很必要。有一个特殊是C 语言宏名,是按 C 语言那种大写加下划线
& & 09:33:12 +08:00
图片异步加载常见的使用场景都是固定图片大小异步加载,如果异步加载后需要重新计算行高再 somehow 重新渲染 UITableViewCell,异步加载无法确定什么时候结束,如果还没结束你往下拉了,异步加载结束了tableView岂不是蹦来蹦去?
方案1:前面有人提到了,用一个「图片」的图标做 placeholder,点击查看大图,这个方案也是我在做的公司项目的做法,还不错
方案2:我自己做过一个类似论坛客户端用的方法是 UIWebView,勉强也可以实现图文混排,似乎算异步请求图片,效果就是上面说的蹦来蹦去
& & 09:43:24 +08:00
@ 下划线一般用在变量和属性,对象和内置类都是驼峰命名
& & 09:48:24 +08:00
其实楼主这种方法貌似不现实啊,抛开解决方案难不说,其实这样的体验并非必须,15楼说的方案不错可以参考。
按照楼主的需求,肯定不能只reload一行吧~
& & 10:01:03 +08:00
@ 请教一下,如果有多个view的高度会变呢,比如说一个cell里的图片有标题,图片加载完成后知道高度,标题如果有多行则显示为多行,这个constraint该怎么设置呢。
& & 10:17:10 +08:00
@ 我还是觉得移动端上采用图片行固定高度的方式好。图片采用等比缩放,始终不变形就还好吧。
& & 10:20:47 +08:00 via iPhone
@ 问题是,一层楼的图片数量也不确定
& & 10:33:09 +08:00 via Android
@ 没说只能一条啊? 如果是iOS8的话auto layout怎么用,他就怎么用。
& & 13:04:23 +08:00
@ 这到也是啊。。。要不做成像微博客户端那种,把图片当做附件另外处理吧。
& & 14:24:15 +08:00
我写的时候通过读取缓存来避免循环 reload cell 的问题。
当然最好的是直接通过图片 URL 加入 hash 来取原始大小。。
& & 15:06:40 +08:00
@ 两个高度可变的控件的constaint不知道怎么设置了。。
& & 16:53:48 +08:00
@ 难道要跟php那么low吗?哈哈哈
& & 16:57:17 +08:00
@ 我一般是弄一个 tempCell,然后 heightForCell 的时候把参数给这个temp然后返回temp的高度,虽然资源占用浪费了一点点,但方便啊,不用自己再去算一遍高。
但这种做法不是最优,也比较浪费资源,正确的做法是,类似微信朋友圈,如果文字多过某个限定值,加一个显示更多。
& & 17:02:43 +08:00
@ 如果比例很夸张,高度固定后,宽度&超出&设备屏幕的怎么处理?
此时:高度还是固定,但是图片居中并限制宽度?
& & 18:43:27 +08:00
@ 我做的不是评论这种的,是每个cell有图片,然后对图片有一个简单的介绍,在图片的下面,还有几个其他的控件,但是位置大小都固定。
& & 19:17:41 +08:00
@ 实在要做的话,那就先给一个loading图片的高度,载入了之后,再reloaddata好了,然后把这个图片对应的高宽记下来,下次用
& & 19:18:05 +08:00
@ 当然, 正确的做法是后台读到图片高宽传给你按比例计算
& & 19:28:48 +08:00
固定大小,如果动态是不是我上传一个1px * 800px的图 你app怎么玩?
& & 19:36:55 +08:00
@ 我用了autolayout,后台返回宽高比,我计算出图片应有的宽高,这个时候是可以知道图片的位置的,但是在storyboard里,这个imageView的contraint怎么设置呢。
& & 20:05:59 +08:00
可以参考一些微博客户端的做法
& & 20:10:37 +08:00
@ 不好意思,autolayout不熟,你设置imageView下面的那堆东西相对于imageView的位置来自动位置,那么只需要设置 imageView frame 的 height,下面就应该会跟着变位置了吧。
& & 20:33:49 +08:00 via iPhone
未經過排版就按原比例顯示很容易打破佈局, 比如說保持 aspect fill 寬度, 那我發一張 1x100 的小圖就可以刷屏了.
& & 20:52:19 +08:00
@ 为什么总考虑极端呢?这种情况加个最大 height 限制不就可以了? 我主要是这种图文混排的实现,极端情况自然会考虑。
& & 23:06:29 +08:00
@ 这时候我倾向于宽度为设备宽度,重新等比例缩放。
& & 23:09:59 +08:00
@ 效果确实没啥好大的问题。这两个客户端,好像都是取回图片之后,按照固定宽度,等比例缩放显示的。
& & 00:25:25 +08:00
按照自己的理解大致写了一下
太晚了,代码还有问题。没有 lazy load,用的是直接加载图片。如果 lazy load 的话,需要缓存一下图片,并且检查发起 lazy load 的 cell 是否可见(继承 DTLazyImageView,增加一个指向 cell 的引用)
明天再改吧
& & 17:00:30 +08:00
没做过,但感觉可以实现。
你先 lazy load,图片到了之后放进 NSTextAttachment 里面,然后扔进 NSAttributedString 里面实现图文混排。最后就可以用 textView.sizeThatFits: 来获得混排之后的高度了。
有了高度之后 reload 一下 cell 就好了嘛。
之前写过一个 NSAttributedString 图文混排的扩展,应该改改就能用。
& &222 天前
请问楼主这个问题解决了吗?请回复,我也遇到同样的问题,急,谢谢
& &222 天前 via iPhone
@ 没有解决。没有很符合需求的 rich text label ,目前尚无时间用 CoreText/TextKit 自己实现。
暂时的解决办法:用一个 WebView
& &83 天前
@ 求问楼主这个问题现在有解决么?
& · & 1709 人在线 & 最高记录 1847 & · &
创意工作者们的社区
World is powered by solitude
VERSION: 3.9.7.3 · 59ms · UTC 02:38 · PVG 10:38 · LAX 19:38 · JFK 22:38? Do have faith in what you're doing.2707人阅读
MAC OS(28)
经测试:对性能影响很大
self.imageView.clipsToBounds = YES;
测试方法:
直接修改UITableViewCell的imageView, 修改前后,界面差别很大
(2) 直接绘制cell 导致问题
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath
*)indexPath
& & [selfconfigCell:(detailListViewTabelCell
*)cellIndexPath:indexPath ];
& & [cellsetNeedsDisplay]; //如果直接绘制, 就需要在每个CELL显示时刷新,这是导致了界面慢的原因
tableView 的性能优化:
(1)使用不透明视图。
不透明的视图可以极大地提高渲染的速度。因此如非必要,可以将table cell及其子视图的opaque属性设为YES(默认值)。
其中的特例包括背景色,它的alpha值应该为1(例如不要使用clearColor);图像的alpha值也应该为1,或者在画图时设为不透明。
(2)减少视图的数目
UITableViewCell包含了textLabel、detailTextLabel和imageView等view,而你还可以自定义一些视图放在它的contentView里。然而view是很大的对象,创建它会消耗较多资源,并且也影响渲染的性能。
如果你的table cell包含图片,且数目较多,使用默认的UITableViewCell会非常影响性能。奇怪的是,使用自定义的view,而非预定义的view,明显会快些
。当然,最佳的解决办法还是继承UITableViewCell,并在其drawRect:中自行绘制:
不过这样一来,你会发现选中一行后,这个cell就变蓝了,其中的内容就被挡住了。
最简单的方法就是cell.selectionStyle = UITableViewCellSelectionStyleN, 这样就不会被高亮了。
此外还可以创建CALayer,将内容绘制到layer上,然后对cell的contentView.layer调用addSublayer:方法。layer并不会显著影响性能,但如果layer透明,或者有圆角、变形等效果,就会影响到绘制速度了。
(3)不要做多余的绘制工作。
在实现drawRect:的时候,它的rect参数就是需要绘制的区域,这个区域之外的不需要进行绘制。
例如上例中,就可以用CGRectIntersectsRect、CGRectIntersection或CGRectContainsRect判断是否需要绘制image和text,然后再调用绘制方法
(4)预渲染图像
在bitmap context里先将其画一遍,导出成UIImage对象,然后再绘制到屏幕。此步很重要! 参考&&
(5)不要阻塞主线程
&& 创建新线程去下载资源
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:391157次
积分:5725
积分:5725
排名:第2673名
原创:155篇
转载:76篇
译文:12篇
评论:76条
(1)(2)(1)(1)(5)(6)(1)(1)(1)(1)(6)(7)(6)(1)(1)(1)(4)(3)(3)(7)(2)(1)(2)(2)(1)(8)(1)(3)(1)(1)(3)(5)(1)(2)(3)(2)(4)(3)(1)(9)(30)(19)(10)(9)(36)(25)IOS详解TableView:性能优化及手工绘制UITableViewCell - 手机系统 - 编程入门网
IOS详解TableView:性能优化及手工绘制UITableViewCell
提高表视图的性能
UITableView作为应用中最常用的视图,它的性能优化问题几乎是经常提及 。下面对在非网络访问情况下的表视图性能优化进行了主要的几点说明:
1.自定义类或XIB文件 时
在系统提供的样式不能满足我们的时候,我们经常会创建自定义类或者XIB文件来自定义单元 格样式。
在之前,我们通常通过loadNib的方式或者在代理方法中继续使用老的方法来设置重用 ,管理缓存池。在IOS6以后,我们可以通过注册的方式在注册单元格甚至表头视图,让系统来更高效的 进行管理。
2.InterfaceBuilder
据说有很多偏执的工程狮们坚持手打代码来完成工程,讨厌拖拖拽拽。 不过随着IB的不断强大,已经有越来越多的人喜欢上了使用IB来建立和管理界面。在新的Xcode5中,IB 又进步了不少。回到正题,尽管如此,在使用高性能的Cell时,还是推荐使用代码来创建单元格类。当 UITableViewCell拥有多个子视图时,IOS的渲染机制会拖慢速度。重写drawRect直接绘制内容的方式可 以提高性能,而不是在类初始化的时候初始化一些label或者imageview等。
3.图层颜色问题
透明图层对渲染性能会有一定的影响,系统必须将透明图层与下面的视图混合起来计算颜色,并 绘制出来。减少透明图层并使用不透明的图层来替代它们,可以极大地提高渲染速度。
4.渲染中 注意的问题
绘制时要尽可能的避免分配资源,比如UIFont,NSDateFormatter或者任何在绘制时 需要的对象,推荐使用类层级的初始化方法中执行分配,并将其存储为静态变量。
5.为代理方法 瘦身
我们经常能看到在项目中,
- (UITableViewCell *)tableView:(UITableView *) tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
这个方法中的代码多的吓人,我 们可以讲一些数据绑定到cell中,或者在有多个tableview的时候,将其绑定到其他的 tableviewcontroller中去。这样可以方便维护和管理,其实也对程序运行性能有很大的帮助。
手工绘制单元格
下面就绘制一个表视图单元格,并在表视图中显示。}

我要回帖

更多关于 uitableviewcell 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信