我有一个UITableView,它充当窗体。它有大约20个单元格(具有静态内容,但具有动态单元格)。所以我有一个包含字段的数组,并将其加载到表视图中。在某个时候,用户将按下"提交"按钮,我需要在表视图的单元格中输入的所有文本字段值。因此,我为每个单元格中的每个文本字段创建了一个@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;
}
只能从可见单元格中检索数据(不可见单元格不存在或包含不适当的数据)。
有几种方法可以做到这一点。对您来说,最好的解决方案是委派(UITextFieldDelegate)。您可以在UITextField中获取有关更改的信息,以便更新数据模型。
在tableView:cellForRowAtIndexPath:
中,您可以将正确的(实际的)数据传递到表单元格(这部分代码已经存在)。
假设您有一个object数组,其中每个对象对应于tableView中的表单字段。当您将单元格出列时,需要将相应的对象分配给UITableViewCell子类。现在让UITableViewCell子类成为的接收器
UITextFieldTextDidChange通知
并保存对模型的更改。
也就是说,它看起来像这样。
@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;
}
}];
}
}
为每个单元格提供了一个不同的标识符,如tableIdentifier=[string stringwithformat:"cellid%@",indexpath.row]。希望这能对您有所帮助。
我可以看到两种可能的方法来解决您的问题。
可能的解决方案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
准备重复使用单元格时,请存储数据。
您可以将此函数添加到单元格对象中,因此当要重用单元格时,您必须检查数据并将其存储在其他地方。
override func prepareForReuse(){
// save data here an then....
super.prepareForReuse()
}