我正在分组的tableview中制作表单。在这种形式中,我有UIswitches和textfields。但在向下滚动后,单元格样式正在发生变化。
这是我的cellForRowAtIndex
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
static NSString *MyIdentifier = @"GenericCell";
cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] ;
}
NSString *text = nil;
if(indexPath.section == CREDENTIALS_SECTION){
if (indexPath.row == 0) {
NSLog(@"tot hier login");
UITextField *login = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
login.adjustsFontSizeToFitWidth = YES;
login.placeholder = @"example@gmail.com";
login.keyboardType = UIKeyboardTypeEmailAddress;
login.returnKeyType = UIReturnKeyNext;
login.backgroundColor = [UIColor clearColor];
login.tag = 0;
login.delegate = self;
[login setEnabled: YES];
[cell addSubview:login];
}else if (indexPath.row == 1){
NSLog(@"tot hier pass");
UITextField *pass = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
pass.adjustsFontSizeToFitWidth = YES;
pass.placeholder = @"Required";
pass.keyboardType = UIKeyboardTypeDefault;
pass.returnKeyType = UIReturnKeyDone;
pass.secureTextEntry = YES;
pass.backgroundColor = [UIColor clearColor];
pass.tag = 0;
pass.delegate = self;
[cell addSubview:pass];
}
if (indexPath.row == 0) { // Email
text = @"Email";
}
else if(indexPath.row == 1) {
text = @"Password";
}
}else if(indexPath.section == METHODS_SECTION){
UISwitch *toggleSwitch = [[UISwitch alloc]initWithFrame:CGRectMake(220, 10, 100, 30)];
toggleSwitch.tag = indexPath.row;
[toggleSwitch addTarget:self action:@selector(toggleSwitched:) forControlEvents:UIControlEventValueChanged];
[cell addSubview:toggleSwitch];
if (indexPath.row == 0) { // Web
text = @"Web applicatie";
}
else if(indexPath.row == 1) { //Mobile
text = @"Mobiele applicatie";
}
else if(indexPath.row == 2) { //Mail
text = @"E-mail";
}
}else if(indexPath.section == PHONE_SECTION){
UITextField *phoneText = [[UITextField alloc] initWithFrame:CGRectMake(20, 10, 185, 30)];
phoneText.adjustsFontSizeToFitWidth = YES;
phoneText.font = [UIFont fontWithName:@"Arial-BoldMT" size:18];
phoneText.keyboardType = UIKeyboardTypeNumberPad;
phoneText.delegate = self;
phoneText.textColor = [UIColor blackColor];
phoneText.text = _person.phone;
[cell addSubview:phoneText];
}else if(indexPath.section == REMARK_SECTION){
UITextView *textView = [[UITextView alloc]initWithFrame:CGRectMake(20, 10, 280, 260)];
textView.text = _person.remark;
textView.delegate = self;
textView.font = [UIFont fontWithName:@"Arial" size:15.0];
textView.backgroundColor = [UIColor clearColor];
[cell addSubview:textView];
text = @"";
}else if(indexPath.section == BUTTON_SECTION){
cell.backgroundColor = [UIColor redColor];
text = @"test";
}
cell.textLabel.text = text;
return cell;
}
经过一番搜索,我发现有更多人遇到这个问题。问题在于这段代码。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = nil;
static NSString *MyIdentifier = @"GenericCell";
cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] ;
}
NSString *text = nil;
但我没有找到解决方案。 希望有人可以帮忙!
亲切的问候!
澄清
Oké所以在这里你看到我的表格的截图。下面我有一个红色单元格(保存按钮),当我向下滚动其他单元格获得红色背景。而一些单元格,文本属性正在发生变化。
答案 0 :(得分:3)
这不是工作的锣。显然你还没有完全理解重用机制是如何工作的。
你做什么的? 首先,您获取要重复使用的单元格。如果你到目前为止得到一个 - 但问题来得更晚。如果你没有得到一个,那么你创建一个新的。
如果您创建了一个新的,在用户开始滚动之前就是这种情况,那么您可以根据节和行添加一些UIItem。我将解释为什么这实际上并不是一件好事。
然后用户滚动。细胞将从屏幕上消失,然后可以重复使用。然后,您将获取单元格以供重复使用。但很可能这些单元格已经有了额外的UI项目,因为你之前已经以这种方式使用过它们。在以下过程中,您将添加新的UI项目,无论该单元格上是否已有其他UI项目。
你能做什么:
创建自己的自定义表格单元子类。您可能需要的每组附加UI项目的一个子类。这可能是最好的方式。对于每个子类,使用不同的重用标识符(!!!) 这是我推荐的! 但是,还有其他选择:
您仍然可以使用您的概念,但为每种类型的单元格创建一个单独类型的重用标识符,其中包含某些类型的附加UI项目。如果是这样,那么请确保仅创建这些UI项并将其作为子视图添加到代码的if (cell == nil)
分支中。只创建一次然后重复使用它们。单元重用-ID可以是“电子邮件显示”,“电子邮件输入”,“密码显示”,“密码输入”,“切换”,......
上面解决方案的方差是,计算行和部分 进入重用标识符。例如0和0的“cell-id-0.2” 第2行 - 左右。但是你仍然必须确保你真的 重复使用其他UI视图,不要每次都重新创建它们 当细胞充满数据时。此外,第一部分的布局取决于您是要输入密码和电子邮件还是只显示它们。您仍然需要处理这些变化。
如果cell == nil - 意味着是否重新使用了一个单元格 - 那么首先从您之前添加的每个UI项目中清除它。你可以通过标记你的UIViews来实现这一点 - 比如99 - (任何不同于0应该做的事情)在创建时以及重用枚举所有子视图并删除那些具有标记99的那些。尽管你可以坚持使用代码你已经做了。
答案 1 :(得分:2)
最简单的解决方法是:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"GenericCell"] ;
//some more code
return cell;
}
这将从tableview中删除可重用性,但由于它是一个有限的设置视图,它可以没问题。我仍然建议从Hermann Klecker的解决方案中选择1或2个。
答案 2 :(得分:1)
如果您还需要保持UIControl状态,请使用
static NSString *MyIdentifier = [NSString stringWithFormat:@"GenericCell%d",indexPath.row];
它将始终返回您唯一的表格行,您可以根据需要使用它。
答案 3 :(得分:0)
尝试从重复使用之前删除单元格中的所有子视图。试试代码:
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] ;
}
else
{
[cell.contentView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)];
}
答案 4 :(得分:0)
在单元格上添加子视图之前删除所有子视图。
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:SimpleTableIdentifier]autorelease];
}
else
{
//To remove the subview of cell.
for (UIView *vwSubviews in [cell.contentView subviews])
{
[vwSubviews removeFromSuperview];
}
}
它可以解决您的问题。
答案 5 :(得分:0)
其实这里有一些不好的代码。
在方法中
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
除非它不在if (cell == nil)
,否则你不应该初始化并使用任何
-(void)addSubview:(UIView*)view
为什么?
单元格是从tableview重用的视图。因此,如果您添加一些子视图,下次重复使用该单元格时,会在其上添加更多子视图。只是它们重叠并可能导致内存泄漏。
不要忘记细胞是可重复使用的。所以;
如果我有以下代码,除非我没有在其他地方设置文本。预计所有单元格的文本标签中都有“这是一个文本”。因为它们是可重复使用的。
if (someChangingBool) {
cell.textLabel.text = @"this is a text";
}
所以我需要有一个其他的,如果它将文本设置为其他东西。