UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件。上面主要是一个个的UITableViewCell,可以让UITableViewCell响应一些点击事件,也可以在UITableViewCell中加入UITextField或者UITextView等子视图,使得可以在cell上进行文字编辑。
UITableView中的cell可以有很多,一般会通过重用cell来达到节省内存的目的:通过为每个cell指定一个重用标识符(reuseIdentifier),即指定了单元格的种类,当cell滚出屏幕时,会将滚出屏幕的单元格放入重用的queue中,当某个未在屏幕上的单元格要显示的时候,就从这个queue中取出单元格进行重用。
但对于多变的自定义cell,有时这种重用机制会出错。比如,当一个cell含有一个UITextField的子类并被放在重用queue中以待重用,这时如果一个未包含任何子视图的cell要显示在屏幕上,就会取出并使用这个重用的cell显示在无任何子视图的cell中,这时候就会出错。
解决方法:
方法1 将获得cell的方法从- (UITableViewCell*)dequeueReusableCellWithIdentifier:(NSString*)identifier 换为-(UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
重用机制调用的就是dequeueReusableCellWithIdentifier这个方法,方法的意思就是“出列可重用的cell”,因而只要将它换为cellForRowAtIndexPath(只从要更新的cell的那一行取出cell),就可以不使用重用机制,因而问题就可以得到解决,虽然可能会浪费一些空间。
示例代码:
[plain] - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; // UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; //改为以下的方法 UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; //根据indexPath准确地取出一行,而不是从cell重用队列中取出 if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } //...其他代码 } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; // UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; //改为以下的方法 UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; //根据indexPath准确地取出一行,而不是从cell重用队列中取出 if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } //...其他代码 }
方法2 通过为每个cell指定不同的重用标识符(reuseIdentifier)来解决。
重用机制是根据相同的标识符来重用cell的,标识符不同的cell不能彼此重用。于是我们将每个cell的标识符都设置为不同,就可以避免不同cell重用的问题了。
示例代码:
[plain] - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d%d", [indexPath section], [indexPath row]]; //以indexPath来唯一确定cell UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; //出列可重用的cell if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } //...其他代码 } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d%d", [indexPath section], [indexPath row]]; //以indexPath来唯一确定cell UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; //出列可重用的cell if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } //...其他代码 }
方法3 删除重用cell的所有子视图
这个方法是通过删除重用的cell的所有子视图,从而得到一个没有特殊格式的cell,供其他cell重用。
示例代码:
[plain] - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; //出列可重用的cell if (cell == nil) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]; } else { //删除cell的所有子视图 while ([cell.contentView.subviews lastObject] != nil) { [(UIView*)[cell.contentView.subviews lastObject] removeFromSuperview]; } } //...其他代码 }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。
我试图复制段落内容时,我点击它,我写了这段代码,但它不能正常工作 代码如下:
我正在尝试解决类似于员工名册的问题。我面临的问题是,每次我运行求解器时,它都会生成不同的任务。这使得更难调试为什么选择特定案例而不是另一个案例。为什么会这样? 附注:我的任务有许多硬性限制,可能无法全部满足(大多数情况下,我仍然看到一些负面的硬性评分)。所以我的终止策略是基于< code > unimprovedSecondsSpentLimit 。会不会是这个原因?
本文向大家介绍Ajax局部更新导致JS事件重复触发问题的解决方法,包括了Ajax局部更新导致JS事件重复触发问题的解决方法的使用技巧和注意事项,需要的朋友参考一下 如果在页面中包含一个ajax更新的列表,那么需要小心非动态更新部分的事件处理。 以带有公共工具栏的列表界面为例: | Menu1 | Menu2 ---------------------------------------------
相对来说,我是ReactJS的初学者。我一直在寻找这个问题的答案。我有一份表格,要分成两部分。第一部分包含一些文本输入和单选按钮。在第1部分的末尾有一个继续按钮。按钮如下: 这是继续按钮的单击处理程序: 因此,单击继续按钮后,我必须将数据存储在数据库中,然后转到表单的第2部分,该部分将显示在新页面上。有没有一种方法可以重定向到第2部分从句柄单击()?如果没有,我还能如何用最少的代码实现它? 提前谢
本文向大家介绍PHP脚本内存泄露导致Apache频繁宕机解决方法,包括了PHP脚本内存泄露导致Apache频繁宕机解决方法的使用技巧和注意事项,需要的朋友参考一下 在部署一套内网测试环境时,频繁宕机,开机后不断的吃内存,重启apache之后内存占用会不停的上涨,直到swap用完,直到死机,由于是内网环境,服务器并发和压力都很小。 查看apache错误日志,报大量类似错误: 后查出来是因为php某一
我在一个商业android应用程序上工作。我还在使用一些根据不同许可证类型授权的库,其中一些声明如下: 如果库中有一个带有属性注释的“通知”文件,则在分发时必须包含该通知 (例如,其中一个是Apache License 2.0许可的)。 图书馆不止一个。当我使用gradle或Android Studio进行构建时,我得到以下构建错误: 根据这些库的许可证(例如Apache许可证2.0),应该包括许
我在Intellij Idea 15(jdk1.8u60)中创建了一个grails 2.4.4项目。当我尝试运行我的项目时,我生成了一个长而无休止的日志: 我如何运行我的项目?
本文向大家介绍iOS App中UITableView左滑出现删除按钮及其cell的重用,包括了iOS App中UITableView左滑出现删除按钮及其cell的重用的使用技巧和注意事项,需要的朋友参考一下 UITableView的编辑模式 实现UITableView简单的删除功能(左滑出现删除按钮) 首先UITableView需要进入编辑模式。实现下面的方法,即使什么代码也不写也会进入编辑模式: