xcode 当 UITableView 滚动时,数据在 UITableViewCell 上丢失?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/9835091/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Data lose On UITableViewCell When UITableView Scrolling?
提问by John
I am trying to implement UITableview
based application. In my tableView
their is 10 Section and each section having one row.
I want implement each section have Different type of ContentView
(1-8 same ContentView
9th section Different ContentView
). I did this code For that.
我正在尝试实现UITableview
基于应用程序。在我tableView
他们是 10 节,每节有一行。我想实现每个部分都有不同的类型ContentView
(1-8 相同的ContentView
第 9 部分不同ContentView
)。我为此做了这个代码。
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 10;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return 1;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier1 = @"Cell1";
static NSString *CellIdentifier2 = @"Cell2";
UITextField *textField;
UITextView *textView;
NSUInteger section=[indexPath section];
if(section == 9){
UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];
//UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if(cell==nil){
cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1]autorelease];
textView=[[UITextView alloc]initWithFrame:CGRectMake(5, 5, 290, 110)];
[textView setBackgroundColor:[UIColor scrollViewTexturedBackgroundColor
]];
[textView setTag:([indexPath section]+100)];
[cell.contentView addSubview:textView];
}else{
textView=(UITextView*)[cell.contentView viewWithTag:([indexPath section]+100)];
}
return cell;
}else {
UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];
// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if(cell==nil){
cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2]autorelease];
textField=[[UITextField alloc]initWithFrame:CGRectMake(5, 5, 290, 50)];
[textField setBackgroundColor:[UIColor scrollViewTexturedBackgroundColor]];
[textField setTag:([indexPath section]+100)];
[cell.contentView addSubview:textField];
}else{
textField=(UITextField*)[cell.contentView viewWithTag:([indexPath section]+100)];
}
return cell;
}
return nil;
}
My problem are:
1. After type some thing in the UITextField
/UITextView
i am scrolling in the UITableView
. that time all data in the UITableViewCell
(UITextField
/UITextView
) was lose, except last cell data.
2. If i create cell
我的问题是:1,键入一些东西后的UITextField
/UITextView
我在滚动UITableView
。那个时候UITableViewCell
( UITextField
/ UITextView
)中的所有数据都丢失了,除了最后一个单元格数据。2.如果我创建单元格
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
Instead of
代替
UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];
Data will repeating . How can i over come this problem?
数据会重复。我怎样才能克服这个问题?
回答by jrturton
This line:
这一行:
UITableViewCell *cell=[self.tableView cellForRowAtIndexPath:indexPath];
Should never appear in your data source cellForRowAtIndexPath method.
永远不应出现在您的数据源 cellForRowAtIndexPath 方法中。
Apart from that, your code is OK, except that you are not setting the text field value anywhere. You need a model (such as an array of strings for the 10 textfield values). This model should be updated when the textfields are edited, and in your method above you copy the value back out of the model and into the textfield's text property:
除此之外,您的代码还可以,只是您没有在任何地方设置文本字段值。您需要一个模型(例如 10 个文本字段值的字符串数组)。编辑文本字段时应更新此模型,并且在上面的方法中,您将值从模型中复制回文本字段的文本属性:
textfield.text = [self.modelArray objectAtIndex:indexPath.section];
回答by danh
The table pools and reuses cells in an unpredictable fashion, so that subview of a cell that just scrolled off the bottom might reappear next at the top, or might be disposed of.
表格以不可预测的方式合并和重用单元格,因此刚刚从底部滚动的单元格的子视图可能会再次出现在顶部,或者可能会被处理掉。
This is why you saw it partially work. The cell's subviews work okay until their cell gets reused or unloaded, then things move to the wrong place or data disappears.
这就是您看到它部分工作的原因。单元格的子视图工作正常,直到它们的单元格被重用或卸载,然后事情移动到错误的地方或数据消失。
The solution is that your table's datasource needs to hold onto it's own data. This is usually an array representing your model. Your case is a little unusual because you are using the text controls in your table as inputs, rather than display, which is more typical.
解决方案是您的表的数据源需要保留它自己的数据。这通常是一个代表您的模型的数组。您的情况有点不寻常,因为您使用表格中的文本控件作为输入,而不是更典型的显示。
I suggest doing it like this:
我建议这样做:
// in @interface
@property (nonatomic, retain) NSMutableArray *sections;
// in @implementation
@synthesize sections=_sections;
// at some point before the view appears
self.sections = [NSMutableArray array];
for (int i=0; i<10; i++) {
UIControl *textControl;
if (i<9) {
textControl=[[UITextView alloc]initWithFrame:CGRectMake(5, 5, 290, 110)];
} else {
textControl=[[UITextField alloc]initWithFrame:CGRectMake(5, 5, 290, 50)];
}
[textControl setBackgroundColor:[UIColor scrollViewTexturedBackgroundColor]];
[textControl setTag:i+100];
[sections addObject:textControl];
[textControl release];
}
Now your cellForRowAtIndexPath is a little simpler:
现在你的 cellForRowAtIndexPath 稍微简单一点:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier1 = @"Cell1";
static NSString *CellIdentifier2 = @"Cell2";
NSUInteger section=[indexPath section];
if(section == 9) {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier1];
if(cell==nil) {
cell=[[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier1]autorelease];
}
} else {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier2];
if(cell==nil) {
cell = [[[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier2]autorelease];
}
}
// who knows what subview this cell has? it might not have one, or it might have the wrong one
// just clean it up to be certain
for (UIView *view in cell.subviews) {
[view removeFromSuperView];
}
// get the textControl we set up for _this_ section/cell
UIControl *textControl = [self.sections objectAtIndex:section];
// now we have a fresh cell and the right textControl. drop it in
[cell addSubview:textControl];
return cell;
}
回答by danh
I had same issue. Its not the problem with table class. The issue is at the place where you are calling this tableviewcontroller. First make the object of this call in .h and then allocate in .m, thats it..
我有同样的问题。这不是表类的问题。问题出在您调用此 tableviewcontroller 的地方。首先在.h中创建这个调用的对象,然后在.m中分配,就是这样..
When I was declaring in viewdidload like tbl *t = [self.storyboard...];
, I was also facing the same problem. But when I put tbl *t;
in .h problem solved.
当我在 viewdidload like 中声明时tbl *t = [self.storyboard...];
,我也面临同样的问题。但是当我tbl *t;
输入 .h 问题就解决了。
回答by PJR
hey the reason is you are doing this things when cell is nil ? but you are not writing any code when cell is not nil.
嘿,原因是当单元格为零时你正在做这些事情吗?但是当单元格不为零时,您没有编写任何代码。
look at this example , in this example i am adding image view in tableview cell , hence you can add textviews or any other views like this
看看这个例子,在这个例子中,我在 tableview 单元格中添加图像视图,因此你可以添加文本视图或任何其他这样的视图
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
UIImageView *imgView;
if(cell == nil)
{
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
imgView = [[UIImageView alloc] initWithFrame:CGRectMake(100,0,100,62)];
[imgView setImage:[UIImage imageNamed:@"img.png"]];
imgView.tag = 55;
[cell.contentView addSubview:imgView];
[imgView release];
}
else
{
imgView = (id)[cell.contentView viewWithTag:55];
}
so as showin here imgView = (id)[cell.contentView viewWithTag:55];you have to give tag to you and write code showing above in else..
所以如图所示 imgView = (id)[cell.contentView viewWithTag:55]; 你必须给你标签,并在 else.. 中编写上面显示的代码。
回答by Minkle Garg
Let you try to make the cell labels and textviews by using following code. It works for me.
让您尝试使用以下代码制作单元格标签和文本视图。这个对我有用。
if (tagvalue ==3) {
static NSString *CellIdentifier = @"Cell3";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier] autorelease];
}
lbl7 = [[UILabel alloc] init];
[lbl7 setFont:[UIFont boldSystemFontOfSize:20]];
[cell.contentView addSubview:lbl7];
lbl7.backgroundColor = [UIColor clearColor];
lbl7.frame = CGRectMake(120, 5, 0, 40);
lbl7.tag = 70;
[lbl7 release];
lbl8 = [[UILabel alloc] init];
[lbl8 setFont:[UIFont boldSystemFontOfSize:18]];
[cell.contentView addSubview:lbl8];
lbl8.backgroundColor = [UIColor clearColor];
lbl8.textColor = [UIColor grayColor];
lbl8.frame = CGRectMake(120, 50, 0, 40);
lbl8.tag = 80;
[lbl8 release];
lbl7 = (UILabel*)[cell.contentView viewWithTag:70];
lbl8 = (UILabel*)[cell.contentView viewWithTag:80];
lbl7.text = [[rowsarray objectAtIndex:row]objectForKey:@"name"];
lbl8.text = [[rowsarray objectAtIndex:row]objectForKey:@"flavour"];
[lbl7 sizeToFit];
[lbl8 sizeToFit];
return cell;
}
if (tagvalue ==4) {
static NSString *CellIdentifier = @"Cell4";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
lbl9 = [[UILabel alloc] init];
[lbl9 setFont:[UIFont boldSystemFontOfSize:20]];
[cell.contentView addSubview:lbl9];
lbl9.backgroundColor = [UIColor clearColor];
lbl9.frame = CGRectMake(120, 5, 0, 40);
lbl9.tag = 90;
[lbl9 release];
lbl10 = [[UILabel alloc] init];
[lbl10 setFont:[UIFont boldSystemFontOfSize:18]];
[cell.contentView addSubview:lbl10];
lbl10.backgroundColor = [UIColor clearColor];
lbl10.textColor = [UIColor grayColor];
lbl10.frame = CGRectMake(120, 50, 0, 40);
lbl10.tag = 100;
[lbl10 release];
lbl9 = (UILabel*)[cell.contentView viewWithTag:90];
lbl10 = (UILabel*)[cell.contentView viewWithTag:100];
lbl9.text = [[rowsarray objectAtIndex:row]objectForKey:@"name"];
lbl10.text = [[rowsarray objectAtIndex:row]objectForKey:@"flavour"];
[lbl9 sizeToFit];
[lbl10 sizeToFit];
return cell;
}