UITableview - 为单元格设置 属性 与重复使用的单元格混淆
UITableview - Setting a property for cell is messed up with reused cells
我有一个用作表单的 UITableView。
它有大约 20 个单元格(具有静态内容但动态单元格)。
所以我有一个包含字段的数组并将其加载到 table 视图中。
有时用户会按下 "Submit" 按钮,我需要在 table 视图的单元格中输入的所有文本字段值。
所以我为每个单元格中的每个文本字段创建了一个 @property
并在 cellForRowAtIndexPath:
.
中分配它
if (indexPath.row==RPCVehicleType || indexPath.row==RPCExcess || indexPath.row==RPCDrivers){
static NSString *tableIdentifier = @"TextFieldArrowCell";
TextFieldArrowCell *cell = (TextFieldArrowCell*)[tableView dequeueReusableCellWithIdentifier:tableIdentifier];
if (cell == nil) {
cell = [[TextFieldArrowCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableIdentifier];
}
switch (indexPath.row) {
case RPCVehicleType:
self.typeOfVehicleTextfield = cell.valueField;
break;
case RPCExcess:
self.excessTextfield = cell.valueField;
break;
case RPCDrivers:
self.driversTextfield = cell.valueField;
break;
default:
break;
}
return cell;
这段代码的问题是,当我滚动到底部时,单元格被重复使用并且属性被弄乱了。因此,当我第一次执行 [self.excessTextField setText:@"123"]
时没问题,但在滚动并再次执行后,我可以看到相同类型单元格的其他文本字段更改为该值。
有解决此问题的解决方法吗?
更新:
尝试了这种方法,结果相同:
-(UITextField*)getTextFieldForRow:(NSInteger)row{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
TextFieldArrowCell *cell = [self.tableV cellForRowAtIndexPath:indexPath];
return cell.valueField;
}
我可以看到 2 种可能的方法来解决您的问题。
可能的解1
使用您自己的单元格而不重复使用它们,在这种情况下,您将始终可以访问存储在文本字段中的信息。
这是 Swift 中的示例代码,可轻松翻译为 Objective-c
var myCellArray:[TextFieldArrowCell?] = Array.init(count: 3, repeatedValue: nil)
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
if (myCellsArray[indexPath.row] == nil) {
myCellsArray[indexPath.row] = UITableViewCell(style: .Default, reuseIdentifier: "TextFieldArrowCell") as! TextFieldArrowCell
//Config the cell
}
return myCellsArray[indexPath.row]
}
最后,在保存按钮中,查询你的数组,并读取文本字段的数据。
可能的解法2
准备重用单元格时,存储数据。
你可以给你的cell对象添加这个功能,所以当cell要被重用的时候,你必须检查数据并存储在其他地方。
override func prepareForReuse(){
// save data here an then....
super.prepareForReuse()
}
假设您有一个对象数组,其中每个对象对应于您的 tableView 中的表单字段。当您出列一个单元格时,您需要将相应的对象分配给您的 UITableViewCell 子类。
现在让你的 UITableViewCell 子类成为
的接收者
UITextFieldTextDidChangeNotification
并保存对模型的更改。
即它看起来像这样。
@interface MyObject: NSObject
@property (strong, nonatomic) NSString *someValue;
@end
// Dequeue your cell..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];
// Assign an object to your cell
cell.object = arrayOfObjects[indexPath.row];
return cell;
}
// Register cell as an observer
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier]) {
// Your init code
[[NSNotificationCenter defaultCenter] addObserverForName:UITextFieldTextDidChangeNotification
object:self.textField
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification * _Nonnull note) {
if ([note.object isEqual:self.textField]) {
self.object.value = self.textField.text;
}
}];
}
}
为每个单元格提供不同的标识符,如表标识符 = [字符串字符串格式:"cellid%@",indexpath.row]。希望对您有所帮助。
您只能从可见单元格中检索数据(不可见单元格不存在或它们包含不适当的数据)。
有几种方法可以做到这一点。
对于您来说,最好的解决方案是委托 (UITextFieldDelegate)。
您可以获得有关 UITextField 更改的信息,因此您可以更新您的数据模型。
在 tableView:cellForRowAtIndexPath:
中,您将正确的(实际)数据传递给 table 单元格(这部分代码您已经有了)。
我有一个用作表单的 UITableView。
它有大约 20 个单元格(具有静态内容但动态单元格)。
所以我有一个包含字段的数组并将其加载到 table 视图中。
有时用户会按下 "Submit" 按钮,我需要在 table 视图的单元格中输入的所有文本字段值。
所以我为每个单元格中的每个文本字段创建了一个 @property
并在 cellForRowAtIndexPath:
.
if (indexPath.row==RPCVehicleType || indexPath.row==RPCExcess || indexPath.row==RPCDrivers){
static NSString *tableIdentifier = @"TextFieldArrowCell";
TextFieldArrowCell *cell = (TextFieldArrowCell*)[tableView dequeueReusableCellWithIdentifier:tableIdentifier];
if (cell == nil) {
cell = [[TextFieldArrowCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:tableIdentifier];
}
switch (indexPath.row) {
case RPCVehicleType:
self.typeOfVehicleTextfield = cell.valueField;
break;
case RPCExcess:
self.excessTextfield = cell.valueField;
break;
case RPCDrivers:
self.driversTextfield = cell.valueField;
break;
default:
break;
}
return cell;
这段代码的问题是,当我滚动到底部时,单元格被重复使用并且属性被弄乱了。因此,当我第一次执行 [self.excessTextField setText:@"123"]
时没问题,但在滚动并再次执行后,我可以看到相同类型单元格的其他文本字段更改为该值。
有解决此问题的解决方法吗?
更新: 尝试了这种方法,结果相同:
-(UITextField*)getTextFieldForRow:(NSInteger)row{
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:row inSection:0];
TextFieldArrowCell *cell = [self.tableV cellForRowAtIndexPath:indexPath];
return cell.valueField;
}
我可以看到 2 种可能的方法来解决您的问题。
可能的解1
使用您自己的单元格而不重复使用它们,在这种情况下,您将始终可以访问存储在文本字段中的信息。
这是 Swift 中的示例代码,可轻松翻译为 Objective-c
var myCellArray:[TextFieldArrowCell?] = Array.init(count: 3, repeatedValue: nil)
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
if (myCellsArray[indexPath.row] == nil) {
myCellsArray[indexPath.row] = UITableViewCell(style: .Default, reuseIdentifier: "TextFieldArrowCell") as! TextFieldArrowCell
//Config the cell
}
return myCellsArray[indexPath.row]
}
最后,在保存按钮中,查询你的数组,并读取文本字段的数据。
可能的解法2
准备重用单元格时,存储数据。
你可以给你的cell对象添加这个功能,所以当cell要被重用的时候,你必须检查数据并存储在其他地方。
override func prepareForReuse(){
// save data here an then....
super.prepareForReuse()
}
假设您有一个对象数组,其中每个对象对应于您的 tableView 中的表单字段。当您出列一个单元格时,您需要将相应的对象分配给您的 UITableViewCell 子类。 现在让你的 UITableViewCell 子类成为
的接收者UITextFieldTextDidChangeNotification
并保存对模型的更改。
即它看起来像这样。
@interface MyObject: NSObject
@property (strong, nonatomic) NSString *someValue;
@end
// Dequeue your cell..
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"];
// Assign an object to your cell
cell.object = arrayOfObjects[indexPath.row];
return cell;
}
// Register cell as an observer
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier]) {
// Your init code
[[NSNotificationCenter defaultCenter] addObserverForName:UITextFieldTextDidChangeNotification
object:self.textField
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification * _Nonnull note) {
if ([note.object isEqual:self.textField]) {
self.object.value = self.textField.text;
}
}];
}
}
为每个单元格提供不同的标识符,如表标识符 = [字符串字符串格式:"cellid%@",indexpath.row]。希望对您有所帮助。
您只能从可见单元格中检索数据(不可见单元格不存在或它们包含不适当的数据)。
有几种方法可以做到这一点。 对于您来说,最好的解决方案是委托 (UITextFieldDelegate)。 您可以获得有关 UITextField 更改的信息,因此您可以更新您的数据模型。
在 tableView:cellForRowAtIndexPath:
中,您将正确的(实际)数据传递给 table 单元格(这部分代码您已经有了)。