在 UITableView 内时 UITextField 中的文本重复
Posted
技术标签:
【中文标题】在 UITableView 内时 UITextField 中的文本重复【英文标题】:Duplicates of text in UITextField when inside UITableView 【发布时间】:2013-03-16 13:33:45 【问题描述】:我在UITableView
中创建了一个UITextField
。我输入数据并关闭键盘。但是,当我向下滚动并隐藏 UITextField
然后再次向上滚动时,'UITextField' 数据被复制,如下所示:
视图的原始负载:
输入数据:
隐藏文本字段后再次开始编辑:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
if ([indexPath section] == 0) // Email & Password Section
cell.textLabel.text = @"Subject";
else
cell.textLabel.text = @"Task";
cell.selectionStyle = UITableViewCellSelectionStyleNone;
if ([indexPath section] == 0)
UITextField *subject = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
subject.adjustsFontSizeToFitWidth = YES;
subject.textColor = [UIColor blackColor];
if ([indexPath row] == 0)
subject.placeholder = @"Maths";
subject.keyboardType = UIKeyboardTypeEmailAddress;
subject.returnKeyType = UIReturnKeyNext;
subject.backgroundColor = [UIColor clearColor];
subject.autocorrectionType = UITextAutocorrectionTypeNo;
subject.autocapitalizationType = UITextAutocapitalizationTypeWords;
subject.tag = 0;
subject.clearButtonMode = UITextFieldViewModeNever;
[cell.contentView addSubview:subject];
else
UITextView *task = [[UITextView alloc] initWithFrame:CGRectMake(102, 0, 185, 40)];
task.text = @"fasfashfjasfhasfasdjhasgdgasdhjagshjdgashjdgahjsdghjasgasdashgdgjasd";
task.editable = NO;
task.scrollEnabled = NO;
task.userInteractionEnabled = NO;
task.textColor = [UIColor colorWithRed: 62.0/255.0 green: 85.0/255.0 blue:132.0/255.0 alpha:1.0];
task.backgroundColor = [UIColor clearColor];
return cell;
【问题讨论】:
发布您的 textField 委托方法 【参考方案1】:就像 Richard 所说,单元格被重复使用(这就是标识符的目的),这就是为什么您在 tableView:cellForRowAtIndexPath:
中测试由 dequeueReusableCellWithIdentifier:
返回的 nil
值。
如果一个单元格已经存在(即之前分配的)并且不再显示,dequeueReusableCellWithIdentifier:
将使用这个单元格来显示新出现的单元格的内容。
您所做的是在每次显示而不是创建单元格时添加您的UITextView
。因此,每次将一个单元格滚动出屏幕并弹出一个新单元格时,您都会在单元格中附加一个新的UITextView
。您应该只在方法的if (cell == nil)
部分添加子视图。由于您的单元格的内容非常不同,我建议使用两个不同的标识符。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifierForSection0 = @"Cell0";
static NSString *CellIdentifierForSection1 = @"Cell1";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: [indexPath section] == 0 ? CellIdentifierForSection0 : CellIdentifierForSection1];
if (cell == nil)
if ([indexPath section] == 0) // Email & Password Section
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifierForSection0];
cell.textLabel.text = @"Subject";
UITextField *subject = [[UITextField alloc] initWithFrame:CGRectMake(110, 10, 185, 30)];
subject.adjustsFontSizeToFitWidth = YES;
subject.textColor = [UIColor blackColor];
if ([indexPath row] == 0)
subject.placeholder = @"Maths";
subject.keyboardType = UIKeyboardTypeEmailAddress;
subject.returnKeyType = UIReturnKeyNext;
subject.backgroundColor = [UIColor clearColor];
subject.autocorrectionType = UITextAutocorrectionTypeNo;
subject.autocapitalizationType = UITextAutocapitalizationTypeWords;
subject.tag = 0;
subject.clearButtonMode = UITextFieldViewModeNever;
[cell.contentView addSubview:subject];
else
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifierForSection1];
cell.textLabel.text = @"Task";
UITextView *task = [[UITextView alloc] initWithFrame:CGRectMake(102, 0, 185, 40)];
task.text = @"fasfashfjasfhasfasdjhasgdgasdhjagshjdgashjdgahjsdghjasgasdashgdgjasd";
task.editable = NO;
task.scrollEnabled = NO;
task.userInteractionEnabled = NO;
task.textColor = [UIColor colorWithRed: 62.0/255.0 green: 85.0/255.0 blue:132.0/255.0 alpha:1.0];
task.backgroundColor = [UIColor clearColor];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
请注意,此代码主要用于示例目的,可以大大减少。此外,您应该像 Richard 建议的那样使用 UITableViewCell
的子类,因为它有助于组织您的代码并使其更具可重用性。
但是不要使用drawRect:
添加子视图。这是不必要的,会影响性能。 drawRect:
仅应在您打算像使用 CoreAnimation 或 CoreGraphics 一样制作真实绘图时使用。添加子视图应在initWithFrame:
或initWithCoder:
中完成,具体取决于您是否使用Interface Builder。
【讨论】:
我会改成UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier: [indexPath section] == 0 ? CellIdentifierForSection0 : CellIdentifierForSection1];
【参考方案2】:
记住单元格会被重用,因此每次重用时都会添加子视图。如果要向单元格添加子视图,最好创建UITableViewCell
的子类并在该子类的drawRect:
方法中添加子视图。这样,修改是单元格的一部分,不会在每次重用单元格时添加。
【讨论】:
在drawRect:
中添加子视图是一个糟糕的主意。你不应该那样做。来自the docs:you do not need to override this method if your view just displays a background color or if your view sets its content directly using the underlying layer object
。
我的立场是正确的,代码应该进入初始化程序。现在,UITableVIewCell
原型也可以做很多事情。
我从来没有说过你错了。只是在你的回答中指出不好的做法:)。以上是关于在 UITableView 内时 UITextField 中的文本重复的主要内容,如果未能解决你的问题,请参考以下文章
使 UITextField 子视图成为 UITableView 中的第一响应者时出错
UITableView 不在 UIScrollView 内滚动
在通过数据源创建的 UITextField 中显示占位符文本
需要在 Swift 中的 UITextField 委托方法中引用自定义 UITableViewCell 而不使用 tag 属性