uitableviewstylecell可以相互切换吗

在中。我们讲了单一样式的UITableViewCell在Autolayout下的动态高度,本文将在上文的基础上,增加两个地方:
1. 多个样式的UITableViewCell类型。
2. UITableViewCell内的数据变化。
完成这样一个程序,TableView中的Cell模拟下载过程,等“下载”完成后,切换到另一个样式的Cell。整个Cell使用Autolayout规划,可以正确运行在iOS 7和iOS 6中(Autolayout最低要求iOS 6),如下图:
(可以看到下载过程中只能显示7个Cell,但是下载完成后Cell高度发生了变化,可以显示8个项目)
整个方式首先沿用的描述的方法,即在heightForRowAtIndexPath中使用dequeueReusableCellWithIdentifier来获取Cell并返回Cell的动态高度,接着根据IndexPath缓存这个Cell,最后在cellForRowAtIndexPath中直接使用这个Cell,因为在cellForRowAtIndexPath方法调用前,全部Cell都会被调用heightForRowAtIndexPath的。
而在本例中,会有两个Cell刷新的问题,一个是Cell内数据刷新,另一个是多个Cell进行切换刷的问题。
所以本例的方案是这样的:在ViewController中缓存一个专门的对象,把它叫做Cache,这个Cache存储着任务本身的数据,对应的Cell,以及Cell是否需要刷新的一个flag(默认是YES)和计算后的Cell高度。当这个是否刷新的flag为YES时,heightForRowAtIndexPath会执行计算高度的逻辑并返回这个高度,如果这个flag是NO,那么heightForRowAtIndexPath会直接返回缓存的高度。注意这个可以节省很多效率,这个在上文详细讲过,因为需要获取动态高度,Cell必须在heightForRowAtIndexPath中被创建,因此每个任务会有一个Cell,而比如有100个任务下载完成后都切换(刷新)了Cell,那么heightForRowAtIndexPath会被调用10000遍,如果每次都要重新计算Cell高度的话,这会成为一笔很大的开销。
OK,接着使用KVO来监控每一个任务数据的变化,变化分为两种,一种是Cell内的变化(本例中的Progress变化,但是还没有下载完成),另一种是Cell切换(从正在下载切换到下载完成状态的变化)。对于第一种变化,直接修改Cache中数据对应的Cell数据就可以了,而对于第二种变化,需要重新设置Cache的Cell,然后设置需要刷新flag为YES就可以了。
来简单说一下过程(具体请参考源代码):
首先,选中Storyboard中TableView,把Prototype Cells从1改成2。这样就有两个Prototype Cell了:
然后设计好两个Cell的UI:
注意每个Cell都定义好Autolayout,并且上下都连接上Constraint,否则systemLayoutSizeFittingSize方法不会返回正确的结果,如下图:
最后别忘了为每一个Cell设置自己的Reuse Identifier。
然后代码上,创建好相应模拟任务的数据对象类型。接下来使用源代码提供的MyCellCache类型(就是上面提到的Cache所代表的的类型):
@interface MyCellCache : NSObject
//缓存的Cell
@property (nonatomic, strong) UITableViewCell *
//计算的高度
@property (nonatomic, assign) CGFloat
//额外数据(可以是Cell的数据)
@property (nonatomic, strong) id
//需要刷新的flag
@property (nonatomic, assign) BOOL needsR
//创建Cache
- (instancetype)initWithCell:(UITableViewCell*)
+ (instancetype)cacheWithCell:(UITableViewCell*)
整个过程和上面描述的是完全一样的,这个类型只不过包装了其中的某些方法。
接着使用另一个类型MyCellCacheList,同样,也是相关方法的封装类型,存储一系列的MyCellCache对象,并且提供方法方便TableView直接调用:
@interface MyCellCacheList : NSObject
@property (nonatomic, strong) NSMutableArray *
//获取Cell和Cell高度,方便TableView调用
- (UITableViewCell*)cellAtIndex:(NSUInteger)
- (CGFloat)cellHeightAtIndex:(NSUInteger)
//列表中的Cell操作
- (void)addCache:(MyCellCache*)
- (MyCellCache*)cacheAtIndex:(NSUInteger)
- (void)setCache:(MyCellCache*)cache atIndex:(NSUInteger)
在ViewController中,创建MyCellCacheList对象:
MyCellCacheList *_cellC
接着通过初始化数据和Cell来创建MyCellCache对象,并把MyCellCache对象加入到ViewController中的MyCellCacheList变量中,这个逻辑上很简单不过代码有些多,就不贴在这里了,读者有兴趣参考下源代码。
然后在TableView的相关方法中就可以直接调用MyCellCacheList的方法,如下:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    return [_cellCache cellAtIndex:indexPath.row];
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    return [_cellCache cellHeightAtIndex:indexPath.row];
最后,在ViewController中使用KVO监听每一个任务数据的变化,并且区分变化的类型,Cell内数据变化则通过Cache获取Cell,并修改Cell内相应UI。如果是Cell切换变化,则需要重新创建相应Cell,并设置Cache的需要刷新flag为YES。
另外注意创建Cell请使用dequeueReusableCellWithIdentifier方法(别忘了再Storyboard中设置Prototype Cell的Reuse Identifier)。
KVO监听方法代码:
//ViewController中的KVO监听方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
    //PATH_PROG是监听的KVO属性字符串
    if ([keyPath isEqualToString:PATH_PROG])
    {
        MyCellCache *cache =
        //通过tag获取Cell的数据对象
        //MyTask类型是任务数据类型(具体参考源代码)
        MyTask *task = cache.tag;
        //获取Cell的index和在TableView中的IndexPath
        NSUInteger index = [_cellCache.cells indexOfObject:cache];
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:index inSection:0];
       
        //如果完成的话,需要切换到另一个Cell
        if (task.isCompleted)
        {
            //设置needsRefresh属性,代表需要刷新这个Cell
            cache.needsRefresh = YES;
            cache.cell = [self getCompletedCell:task];
            //调用reloadRowsAtIndexPaths命令TableView执行刷新
            [self.tableView reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
        }
        else
        {
            //不需要切换Cell,直接修改当前Cell的内容
            NormalCell *normalCell = (NormalCell *)cache.cell;
            normalCell.progressView.progress = task.progress;
        }
    }
我在关键事件加了Log,最后统计结果如下:
UITableView获取高度的次数:420
Cell高度实际计算次数 :40
正在下载Cell被创建次数 :20
下载完成Cell被创建次数 :20
一切看起来还是正常的,有错误欢迎指正。
源代码下载
注意:链接是微软SkyDrive页面,下载时请用浏览器直接下载,用某些下载工具可能无法下载
源代码环境:Xcode 5.0原文链接:1246人阅读
2.自定义颜色和背景设置
&改变UITableViewCell选中时背景色:
UIColor&*color = [[UIColoralloc]initWithRed:0.0green:0.0blue:0.0alpha:1];//通过RGB来定义自己的颜色
3自定义UITableViewCell选中时背景
4.设置tableViewCell间的分割线的颜色
[theTableView setSeparatorColor:[UIColor xxxx ]];
4.pop返回table时,cell自动取消选中状态
首先我有一个UITableViewController,其中每个UITableViewCell点击后都会push另一个ViewController,每次点击Cell的时候,Cell都会被选中,当从push的ViewController返回的时候选中的Cell便会自动取消选中。后来由于某些原因我把这个UITableViewController改成了UIViewController,之后就产生了一个问题:每次返回到TableView的时候,之前选中的Cell不能自动取消选中,经过查找得知:
UITableViewController有一个clearsSelectionOnViewWillAppear的property,
而当把UITableViewController修改成UIViewController后,这个属性自然就不存在了,因此我们必须手动添加取消选中的功能,方法很简单,在viewWillAppear方法中加入:
[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];
6.点击后,过段时间cell自动取消选中
&- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
&&&&&…………
&&&&//消除cell选择痕迹
&&&&[self performSelector:@selector(deselect) withObject:nil afterDelay:0.5f];
- (void)deselect
&&&&[self.tableview deselectRowAtIndexPath:[self.tableview indexPathForSelectedRow] animated:YES];
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:26463次
积分:1104
积分:1104
排名:第16935名
原创:84篇
转载:29篇
(2)(1)(1)(1)(7)(4)(6)(18)(11)(4)(5)(7)(20)(23)(3)UITableViewcell可以相互切换吗_百度知道
UITableViewcell可以相互切换吗
提问者采纳
image给图片,使用[&#47ios开发小记 UITableView 当需要关联不同的数据源来回切换。
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle.imageView :UITableViewCellStyleDefault reuseIdentifier.contentView addS 删除cell中的子对象:UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier.imageV
&#47.contentView!= nil) {
[(UIView*)[cell:object]自定义cell.image = 某个数据源需要cell,导致数据重叠问题以下代码可以解决.subviews lastObject] removeFromSuperview],刷新覆盖问题;&#47.contentView:CellIdentifier].imageView.subviews lastObject] ,其他数据源不需要的话
if (cell!= nil) {
cell:CellIdentifier] autorelease]
提问者评价
其他类似问题
uitableviewcell的相关知识
按默认排序
其他1条回答
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁}

我要回帖

更多关于 uitableview分割线 的文章

更多推荐

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

点击添加站长微信