滚动时自定义 UITableViewCell 中的 UITextFields 文本出现在其他单元格中

Posted

技术标签:

【中文标题】滚动时自定义 UITableViewCell 中的 UITextFields 文本出现在其他单元格中【英文标题】:UITextFields text in custom UITableViewCell appears in other cell while Scrolling 【发布时间】:2015-01-10 10:46:59 【问题描述】:

我是 ios 开发的新手。我在 Xcode 6(故事板)中创建我的应用程序。

我的问题是文本输入到文本字段中,滚动将文本字段文本随机随机排列到其他文本字段的表格视图。我在这样的堆栈溢出中看到了两个问题。但那个答案不是解决问题。

    MoneyEntry.xib 是一个带有一个标签和一个文本框的 uitableviewcell。并向其添加类文件并连接 IBOutlet 并将标识符添加到 uitableviewcell 作为“MoneyEntryIdentifier”。

    //MoneyEntryTableViewCell.h
    
    @interface MoneyEntryTableViewCell : UITableViewCell
    
    //Money Entry Cell
    @property (strong, nonatomic) IBOutlet UILabel *lblMemName;
    @property (strong, nonatomic) IBOutlet UITextField *textAmount;
    
    @end
    
    
    //MoneyEntryTableViewCell.m
    #import "MoneyEntryTableViewCell.h"
    
    @implementation MoneyEntryTableViewCell
    
    @synthesize lblMemName,textAmount;
    - (void)awakeFromNib 
    
    
    - (void)setSelected:(BOOL)selected animated:(BOOL)animated 
    [super setSelected:selected animated:animated];
    
    @end
    

    在 Main.storyboard 添加 UITableView 并连接 IBOutlet 并添加 Datasource 和委托。

    //MoneyDetailViewController.h
    
    #import <UIKit/UIKit.h>
    @interface MoneyDetailViewController : UIViewController
    @property (strong, nonatomic) IBOutlet UITableView *tblVwMoneyEntry;
    @end
    
    
    //MoneyDetailViewController.m
     @interface MoneyDetailViewController ()
     
       NSArray *tabledata;
     
     @end
    
     @implementation MoneyDetailViewController
    
     - (void)viewDidLoad 
      [super viewDidLoad];
      tabledata = [NSArray arrayWithObjects:@"Egg Benedict", @"Mushroom Risotto",@"Full Breakfast", @"Hamburger", @"Ham and Egg Sandwich", @"Creme Brelee",@"White Chocolate Donut", @"Starbucks Coffee", @"Vegetable Curry", nil];
    
    
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
     return [tabledata count];
    
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
     static NSString *CellIdentifier = @"MoneyEntryIdentifier";
     static NSString *CellNib = @"MoneyEntry";
     MoneyEntryTableViewCell *cell = (MoneyEntryTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
     if (cell == nil)
     
      NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
      cell = (MoneyEntryTableViewCell *)[nib objectAtIndex:0];
     
    
     UILabel     *lblname  = (UILabel *)    [cell lblMemName];
     UITextField *txtfield = (UITextField *)[cell textAmount];
     txtfield.tag = indexPath.row;
     lblname.text = [tabledata objectAtIndex:indexPath.row];
     txtfield.placeholder =@"0.00";
     cell.selectionStyle =UITableViewCellSelectionStyleNone;
     return cell;
     
    
    @end
    

请详细解释一下。在此先感谢

【问题讨论】:

【参考方案1】:

我找到了答案.. 只需通过标签文本将文本字段文本放入 Dictionary setObject 并再次通过标签文本检查将文本分配给相应的文本字段.. 这是我的代码...

//In Interface
NSMutableDictionary *amounts;
amounts =[[NSMutableDictionary alloc]init];

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 

static NSString *CellIdentifier = @"MoneyEntryIdentifier";
static NSString *CellNib = @"MoneyEntry";
MoneyEntryTableViewCell *cell = (MoneyEntryTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

if (!cell)

    NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellNib owner:self options:nil];
    cell = (MoneyEntryTableViewCell *)[nib objectAtIndex:0];


UILabel     *lblname  = (UILabel *)    [cell lblMemName];
lblname.tag =100;
UITextField *txtfield = (UITextField *)[cell textAmount];
txtfield.tag =indexPath.row;

[txtfield addTarget:self  action:@selector(textFieldDidChange:) forControlEvents:UIControlEventEditingChanged];
lblname.text = tabledata[indexPath.row];
txtfield.placeholder = [NSString stringWithFormat:@"%ld",(long)indexPath.row];


if ([amounts valueForKey:lblname.text] != nil) 
    txtfield.text = [amounts valueForKey:lblname.text];
 else 
    txtfield.text = @"";


cell.selectionStyle =UITableViewCellSelectionStyleNone;
return cell;


 -(void)textFieldDidChange:(UITextField *)txtField

UILabel *label = (UILabel *)[txtField.superview viewWithTag:100];
NSString *labelString = label.text;
NSString *textFieldString = txtField.text;
[amounts setObject:textFieldString forKey:labelString];

滚动表格视图时没有错误...

【讨论】:

【参考方案2】:

您是否正在做一些事情来存储输入到文本字段中的文本。 UITableView 的工作原理是重复使用不可见或不在屏幕上的 UITableViewCells 以节省内存。

因此,如果您在单元格的文本字段中输入一些文本并且单元格离开屏幕,则该单元格将排队等待以后使用。当您滚动时,会从此队列中添加新行,这会将 textfield 与您之前的文本一起带回。这就是为什么您会看到您的文本随处可见的原因。

您需要将每个textfield 中的数据保存在一个单独的数组中,并在cellForRowAtIndexPath: 函数中将其重置。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    // Your code..
    Item *item = itemArray[indexPath.row]
    cell.txtfield.text = item.amount

您可以使用UITextField's UIControlEventEditingChanged 事件来存储更改后的数组值。

-(void)textFieldDidChange:(UITextField *)txtField

    Item *item = itemArray[txtField.tag] 
    item.amount = txtField.text

你像这样添加 textField 更改方法

[textField addTarget:self 
              action:@selector(textFieldDidChange:) 
    forControlEvents:UIControlEventEditingChanged];

使用一个名为 Item 的自定义类来存储您的数据。

class Item

     @property (nonatomic,strong) NSString *itemName;
     @property (nonatomic) float amount;  

itemArray 将包含您的项目。

Item *it1 = [[Item alloc]init]
it1.itemName = @"Eggs Benedict"
it1.amount = ""
.... 
itemArray = [NSArray arrayWithObjects:it1,it2,it3,nil];

【讨论】:

它不起作用。文本字段不调用 textFieldDidChange 方法。但我将委托添加到文本字段。 textFieldDidChange 不在委托中。请检查我修改后的答案 是的。将文本添加到数量(可变数组)中。滚动时,它将正确的文本返回到编辑的文本字段。但未经编辑的文本字段也有该文本。这是代码if([amounts count] &gt; 0 &amp;&amp; [amounts count] &gt; indexPath.row) txtfield.text=[amounts objectAtIndex:indexPath.row]; 可变数组是不够的。我建议制作一个类项目,其中包含您的项目名称,如本尼迪克蛋和金额。将显示在我的答案中。 你能详细解释一下如何使用它。我之前没有在objective-c中使用类

以上是关于滚动时自定义 UITableViewCell 中的 UITextFields 文本出现在其他单元格中的主要内容,如果未能解决你的问题,请参考以下文章

TableView 滚动时自定义 UITableViewCell 发生变化

添加附件时自定义 UITableViewCell 大小不正确

编辑单元格时自定义 UITableViewCell 反向缩进

调用 reloadData 时自定义 UITableViewCell 内存泄漏

首次加载 UITableViewController 时自定义 UITableViewCell 无法正确显示

实现 willTransitionToState: 时自定义 UITableViewCell 不显示编辑控件