如何实现UITableViewCell中UITextField的值存入对应行的NSString?
解决UITableViewCell中UITextField内容对应存储的方案
嘿,我来帮你搞定这个需求!你要实现的是每个UITableViewCell里的UITextField编辑后,内容对应存到不同的变量(或者更灵活的数组结构里),下面是具体的实现思路和代码示例:
核心思路
其实不用单独维护多个NSString,直接复用你现有的arrProfile数组来存储每个文本框的内容会更灵活(后续数组元素增减时不用修改变量数量)。如果确实需要单独的NSString,也可以在更新数组的同时给这些变量赋值。
我们用自定义UITableViewCell + Block回调的方式来处理编辑事件,比用tag或者单纯的delegate更清晰,避免索引混乱。
步骤1:自定义ProfileCell
先创建一个带UITextField的自定义cell,并且添加block回调来传递编辑事件:
// ProfileCell.h #import <UIKit/UIKit.h> // 定义回调block,传递当前indexPath和编辑后的文本 typedef void(^TextFieldEditingBlock)(NSIndexPath *indexPath, NSString *newText); @interface ProfileCell : UITableViewCell @property (nonatomic, strong) UITextField *detailTextField; @property (nonatomic, strong) NSIndexPath *indexPath; // 记录当前cell的位置 @property (nonatomic, copy) TextFieldEditingBlock editingBlock; // 编辑回调 @end // ProfileCell.m #import "ProfileCell.h" @implementation ProfileCell - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; if (self) { // 创建并配置textField self.detailTextField = [[UITextField alloc] initWithFrame:CGRectMake(16, 8, self.contentView.frame.size.width - 32, 30)]; self.detailTextField.borderStyle = UITextBorderStyleRoundedRect; self.detailTextField.clearButtonMode = UITextFieldViewModeWhileEditing; [self.contentView addSubview:self.detailTextField]; // 监听文本变化(实时更新),也可以用textFieldDidEndEditing实现结束编辑时更新 [self.detailTextField addTarget:self action:@selector(textFieldTextChanged:) forControlEvents:UIControlEventEditingChanged]; } return self; } - (void)textFieldTextChanged:(UITextField *)textField { // 触发回调,把编辑内容和位置传出去 if (self.editingBlock) { self.editingBlock(self.indexPath, textField.text); } } @end
步骤2:在ViewController中配置TableView并处理编辑回调
在你的ViewController里,初始化数组、配置tableView,并在cell回调中更新数据:
// ViewController.m #import "ViewController.h" #import "ProfileCell.h" @interface ViewController () <UITableViewDataSource, UITableViewDelegate> @property (nonatomic, strong) NSMutableArray *arrProfile; @property (nonatomic, strong) UITableView *profileTableView; // 如果你需要单独的NSString变量,在这里声明 @property (nonatomic, strong) NSString *strFName; @property (nonatomic, strong) NSString *strEmail; // ...其他需要的变量 @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 初始化你的数组(替换成你原有的初始化代码) [self.arrProfile removeAllObjects]; self.arrProfile = [[NSMutableArray alloc] initWithObjects: @{@"title": @"CUSTOMER NAME", @"details": self.strFName ?: @""}, @{@"title": @"EMAIL", @"details": self.strEmail ?: @""}, // ...其他元素 nil]; // 创建并添加tableView到视图 self.profileTableView = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain]; self.profileTableView.dataSource = self; self.profileTableView.delegate = self; [self.profileTableView registerClass:[ProfileCell class] forCellReuseIdentifier:@"ProfileCell"]; [self.view addSubview:self.profileTableView]; } #pragma mark - UITableView DataSource - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.arrProfile.count; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { ProfileCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ProfileCell" forIndexPath:indexPath]; cell.indexPath = indexPath; // 从数组取数据,配置cell的标题和文本框内容 NSDictionary *profileDict = self.arrProfile[indexPath.row]; cell.textLabel.text = profileDict[@"title"]; cell.detailTextField.text = profileDict[@"details"]; // 弱引用self避免循环引用 __weak typeof(self) weakSelf = self; cell.editingBlock = ^(NSIndexPath *indexPath, NSString *newText) { // 更新数组:把不可变字典转成可变字典,修改details字段 NSMutableDictionary *mutableDict = [weakSelf.arrProfile[indexPath.row] mutableCopy]; mutableDict[@"details"] = newText; weakSelf.arrProfile[indexPath.row] = mutableDict; // 如果你需要给单独的NSString赋值,根据row索引判断 if (indexPath.row == 0) { weakSelf.strFName = newText; } else if (indexPath.row == 1) { weakSelf.strEmail = newText; // 替换成你的对应变量 } // ...其他row对应的变量赋值 }; return cell; } @end
关键说明
- 为什么用Block而不是Delegate?:Block可以直接在cell配置时绑定当前的
indexPath,不用额外计算cell的位置,代码更简洁,不易出错。 - 实时更新VS结束编辑更新:示例中用的是
UIControlEventEditingChanged实现实时更新,如果你希望用户结束编辑时再保存,可以换成textFieldDidEndEditing方法。 - 数组更新注意点:因为原数组里的字典是不可变的(
NSDictionary),所以必须转成NSMutableDictionary修改后再替换回数组。
内容的提问来源于stack exchange,提问作者Anupam Das
相关产品推荐
相关产品推荐

