操蛋的UITableView重用机制
1,背景
你可能会遇见一下情况:
使用UITableView加载数据,比如你的每一个cell上面有一个UITextField,当你在第一个cell的UITextField中写下了内容,开始下滑UITableView,你会发现由于UITableView重用机制的影响,你的第一个UITextField的值会发生变化,令人费解啊,抓狂!
之类的情况可能很多,下面咱们就总结一下发生这种情况的原因,针对这种原因,咱们找到对应的解决办法。
2,用自己的话说UITableView的重用机制
当遇见这中情况的时候,我问过好多个ios程序员,他们多数的解决办法是直接不让它重用了,当然了,这样的话,表面上确实解决了问题,但是却给自己的程序带来了很大的隐患。我们做东西,应该去想着做最好的东西出来,不能这样草草的应付。
好了,言归正传。
所谓重用机制,就是模板共用一套,换的是内容。比如;view上显示七个cell,当第一个cell消失,第八个cell出现,那么第八个cell用的还是第一个cell,只不过他把第一个cell的内用换成了自己的。这就是重用的原理。问题就出现在他在换内容的时候,没换好,就出现了错误。
那么为什么会出现这种错误呢,为什么我们替换内容的时候根本就没有错,重用后还会出现错误呢?
不说废话 直接说我遇见的问题以及我的解决办法:
我的问题是右边的UITableView在上下滑动的时候按钮出现了重用,点过之后的按钮会发生变化,分成两个按钮,一个加菜按钮一个减菜按钮
当我点了第一个cell后,分裂成功,我将UITableView向下滑,却出现了第一个cell的按钮又变回了原型。
出现的原因:这个cell是我自定义的,这个按钮的状态是没有记录的,一次重用后他会和原来的状态一样。
解决办法:我是这样想的解决办法,之所以个重用是因为第一个和第八个没有特别的标注,我必须想一个区分第一个和第八个的属性,那么就有了indexpath.row,一位他们即使在重用这个值也不会相同,因此我们就用这个属性解决这个操蛋的问题。
好了,原理是这样,来看看我的解决代码吧;
[self.dataArr enumerateObjectsUsingBlock:^(NSDictionary * obj, NSUInteger idx, BOOL *stop) {
[self.tempDotNumberDic setValue:[obj valueForKey:@"number"] forKey:[obj valueForKey:@"ProID"]];
}];
说明:dataArr是tableview的数据源,tempDotNumberDic是一个记录点菜份数的字典,他的key是点菜id(因为id是唯一的,这样可以区分开),他的value是点菜份数。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (tableView.tag == 100)
{
static NSString * strMark = @"cellMark";
DishesClassCell * cell = [tableView dequeueReusableCellWithIdentifier:strMark];
if (cell == nil)
{
cell = [[DishesClassCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strMark];
}
if (indexPath.row<self.myClassArr.count)
{
cell.textContentLab.text = [[self.myClassArr objectAtIndex:indexPath.row] valueForKey:@"ClassName"];
}
if (self.tempClassDic.count>0)
{
NSString * result = [self.tempClassDic valueForKey:[NSString stringWithFormat:@"%d",indexPath.row]];
if ([result isEqualToString:@"1"])
{
cell.backgroundImageView.image = [UIImage imageNamed:@"DishClass06.png"];
}
else
{
cell.backgroundImageView.image = [UIImage imageNamed:@"DishClass05.png"];
}
}
return cell;
} NSString *str1 = [NSString stringWithFormat:@"cellmark%d",selectRow];
NSString * strMark1 = str1; //不停类别用不同的重用标示符,目的是为了不同分类同一位置的重用现象。
DishesDetailListCell * cell1 = [tableView dequeueReusableCellWithIdentifier:strMark1];
__block int dotNumber = 0;
if (indexPath.row < self.myProArr.count)
{
__block NSString * proID;
NSString * currID = [[self.myProArr objectAtIndex:indexPath.row] valueForKey:@"ProID"];
[self.dataArr enumerateObjectsUsingBlock:^(NSDictionary * obj, NSUInteger idx, BOOL *stop) {
proID = [obj valueForKey:@"ProID"];
if ([currID isEqualToString:proID])
{
dotNumber = [[[[DataBase selectNumberFromProId:[currID intValue]] objectAtIndex:0] valueForKey:@"number"] intValue];
}
}];
} if (cell1 == nil)
{
cell1 = [[DishesDetailListCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:strMark1 andDotNumber:dotNumber];
}
cell1.dishView.myLab.text = [NSString stringWithFormat:@"点%d份",dotNumber];
int resylt = [[self.tempDotNumberDic valueForKey:[[self.myProArr objectAtIndex:indexPath.row] valueForKey:@"ProID"]] intValue];
if (resylt == 0)
{
[cell1.dishView zeroState];
}
else
{
[cell1.dishView initView:resylt];
}
if (indexPath.row%2 == 0)
{
cell1.backgroundImageView.image = [UIImage imageNamed:@"5.png"];
}
else
{
cell1.backgroundImageView.image = [UIImage imageNamed:@"6.png"];
}
cell1.selectionStyle=UITableViewCellSelectionStyleNone;
cell1.selectedBackgroundView = [[UIView alloc] initWithFrame:cell1.frame];
cell1.titleLab.text = [[self.myProArr objectAtIndex:indexPath.row] valueForKey:@"ProName"];
NSString * str = @"¥";
NSString * priceStr = [[self.myProArr objectAtIndex:indexPath.row] valueForKey:@"prices"];
cell1.priceLab.text = [str stringByAppendingFormat:@"%@",priceStr];
cell1.dishView.price = [priceStr doubleValue];
cell1.dishView.index = indexPath.row; [cell1.dishView.rightButton addTarget:self action:@selector(rightButtonClickEvent:) forControlEvents:UIControlEventTouchUpInside];
[cell1.dishView.leftButton addTarget:self action:@selector(leftButtonClickEvent:) forControlEvents:UIControlEventTouchUpInside];
[cell1.dishView.bigButton addTarget:self action:@selector(bigButtonClickEvent:) forControlEvents:UIControlEventTouchUpInside]; NSString * pathURL = ALL_URL;
NSURL * url = [NSURL URLWithString:[pathURL stringByAppendingFormat:@"%@",[[self.myProArr objectAtIndex:indexPath.row] valueForKey:@"ProductImg"]]];
[cell1.leftImageView setImageWithURL:url placeholderImage:[UIImage imageNamed:ALL_NO_IMAGE]];
return cell1;
}
看红色部分的代码,这点就是避免问题出现的办法,因为这个值是不同的cell值不同。
感觉自己的想法没有表达清楚,有什么问题直接留言。
操蛋的UITableView重用机制的更多相关文章
- UI之UItableView重用机制的性能问题
*:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...
- IOS开发—UITableView重用机制的了解
引言 对于一个UITableView而言,可能需要显示成百上千个Cell,如果每个cell都单独创建的话,会消耗很大的内存.为了避免这种情况,重用机制就诞生了. 假设某个UITableView有100 ...
- iOS - UITableView中Cell重用机制导致Cell内容出错的解决办法
"UITableView" iOS开发中重量级的控件之一;在日常开发中我们大多数会选择自定Cell来满足自己开发中的需求, 但是有些时候Cell也是可以不自定义的(比如某一个简单的 ...
- iOS基础篇(十三)——UITableView(一)重用机制
UITableView是app开发中常用到的控件,功能很强大,常用于数据的显示.在学习UITableView使用之前,我们先简单了解一下: 1.UITableView的重用机制 UITableView ...
- UITableView动态存放、重用机制
一.UITableView动态存放 #import "ViewController.h"@interface ViewController ()<UITableViewDel ...
- 解决UITableView中Cell重用机制导致内容出错的方法总结
UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件.上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点 ...
- iOS学习笔记(4)— UITableView的重用机制
UITableView中的cell是动态的,在使用过程中,系统会根据屏幕的高度(480)和每个cell的高度计算屏幕中需要显示的cell的个数.比如,cell高度为90.那么480 / 90 = 5 ...
- ios UITableView中Cell重用机制导致内容重复解决方法
UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件.上面主要是一个个的 UITableViewCell,可以让UITableViewCell响应一些点 ...
- iOS之UITableView中的cell因为重用机制导致新的cell的数据出现重复或者错乱
UITableView中的cell可以有很多,一般会通过重用cell来达到节省内存的目的:通过为每个cell指定一个重用标识符(reuseIdentifier),即指定了单元格的种类,当cell滚 ...
随机推荐
- WPF-MVC开发模式简要介绍
1, 建立WPF程序,并在程序中添加三个文件View,ViewMoudle,Moudle, 2,Moudle文件加中添加类,此文件夹中存放的类基本为数据类,主要是字段和属性 3 ViewMoudle文 ...
- sizeof()的用法
机器平台:X86_64 处理器 操作系统:Red Hat 4.1.2-14 编译器: gcc version 4.1.2 20070626 Size of char is: ...
- leetcode Contains Duplicate II python
Given an array of integers and an integer k, find out whether there are two distinct indices i and j ...
- codeforces 632F. Magic Matrix
题目链接 给一个n*n的矩阵, 问是否对角线上的元素全都为0, a[i][j]是否等于a[j][i], a[i][j]是否小于等于max(a[i][k], a[j][k]), k为任意值. 前两个都好 ...
- Tensorflow的CNN教程解析
之前的博客我们已经对RNN模型有了个粗略的了解.作为一个时序性模型,RNN的强大不需要我在这里重复了.今天,让我们来看看除了RNN外另一个特殊的,同时也是广为人知的强大的神经网络模型,即CNN模型.今 ...
- Y5V贴片电容(MLCC)容量范围速查表
Y5V贴片电容简述 Y5V贴片电容属于EIA规定的Class 2类材料的电容.它的电容量受温度.电压.时间变化影响大. Y5V贴片电容特性 具有较差的电容量稳定性,在-25℃-85℃工作温度范围内,温 ...
- cocos2dx CCLayerColor和CCLayerColor
在cocos2dx中,默认的CCLayer背景是黑色的,有些时候需要特殊的Layer,所以cocos2dx中提供了这两种Layer CCLayerColor是可以改变背景色的Layer,示例如下: C ...
- HDU 4957 Poor Mitsui
题解:记答案为ans,已知,对一个确定的顺序,计算所用的时间长短就是从最后向前计算,计算方法如下: ans+=(p[i].b+ans*p[i].a)/(v-p[i].a) 那么,应该如何调整顺序使得答 ...
- 《windows程序设计》学习_3.2:左键的使用
#include<windows.h> #include "resource.h" LRESULT CALLBACK WndProc (HWND, UINT, WPAR ...
- JAVA学习第一课(初识JAVA)
PS:退ACM集训队了,自己也疯玩了两天,后天就开学了,就正式大二了,该收收心好好学习啦 ...