我已经看到每个帖子都接近这个问题,但仍然没有找到有用的东西。我在每个单元格中都有textFields,用作表单供用户填写。除了滚动之外,单元格中的所有内容都能正常工作,当单元格滚出屏幕时,textFields中的输入会消失。我知道这是因为出队。但应该有一种方法来保存输入的数据,以便在滚动或退出应用程序时不会消失。我还希望能够获取此信息并通过电子邮件将其作为PDF或文档发送。实现这一目标的最佳方法是什么?下面的代码是我如何生成单元格等的示例。
.h文件
@interface MasterViewController : UITableViewController <UITextFieldDelegate, UITextFieldDelegate, UITableViewDataSource, UINavigationBarDelegate>{
NSString* name_;
UITextField* nameFieldTextField;
}
// Creates a textfield with the specified text and placeholder text
-(UITextField*) makeTextField: (NSString*)text
placeholder: (NSString*)placeholder;
// Handles UIControlEventEditingDidEndOnExit
- (IBAction)textFieldFinished:(id)sender;
@property (nonatomic,copy) NSString* name;
.m文件
@synthesize name = name_;
- (void)viewDidLoad{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.detailViewController = (DetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
self.name = @"";
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
// Make cell unselectable and set font.
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.font = [UIFont fontWithName:@"ArialMT" size:13];
if (indexPath.section == 0) {
UITextField* tf = nil;
switch ( indexPath.row ) {
case 0: {
cell.textLabel.text = @"Name" ;
tf = nameFieldTextField = [self makeTextField:self.name placeholder:@"John Appleseed"];
nameFieldTextField.tag = 1;
[cell addSubview:nameFieldTextField];
break ;
}
// Textfield dimensions
tf.frame = CGRectMake(120, 12, 170, 30);
// Workaround to dismiss keyboard when Done/Return is tapped
[tf addTarget:self action:@selector(textFieldFinished:) forControlEvents:UIControlEventEditingDidEndOnExit];
}
return cell;
}
// Textfield value changed, store the new value.
- (void)textFieldDidEndEditing:(UITextField *)textField {
//Section 1.
if ( textField == nameFieldTextField ) {
self.name = textField.text ;
}
}
- (void)viewWillAppear:(BOOL)animated{
NSString *nameCellString = [[NSUserDefaults standardUserDefaults] stringForKey:@"nameCellString"];
nameFieldTextField.text = nameCellString;
}
- (void)viewWillDisappear:(BOOL)animated{
NSString *nameCellString = self.name;
[[NSUserDefaults standardUserDefaults] setObject:nameCellString forKey:@"nameCellString"];
}
答案 0 :(得分:1)
这里实际上有两个问题,它们都在你的cellForRowAtIndexPath:
实施中。
您正在将文本字段放入单元格中,即使此单元格已重复使用且已有文本字段。因此,您实际上是在文本字段上堆叠文本字段,覆盖以前存在的文本字段。
如果该行(索引路径)的文本字段中已有文本,则不会将文本放回文本字段。
换句话说,细胞是(正如你所说)重复使用,因此你需要考虑这个事实。您必须查看传入单元的状态,并相应地重新配置单元格。
答案 1 :(得分:1)
首先,我建议你考虑在故事板中创建一个自定义单元格,并抓住它。它比编码一个容易得多,我认为这是未来。也就是说,考虑使用NSArrays填充tableViews,而不是将字符串硬编码到cellForRowAtIndexPath
方法中。我冒昧地给你一个例子。
以下内容基于您的代码,应该是一个复制/粘贴解决方案。仔细看看,看看它是如何运作的。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSArray *titlesArray = @[@"Name", @"Birthday", @"Favorite Food"];
UITableViewCell *cell;
cell = [tableView dequeueReusableCellWithIdentifier:[NSString stringWithFormat:@"%i%i", indexPath.section, indexPath.row]];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
// Make cell unselectable and set font.
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.font = [UIFont fontWithName:@"ArialMT" size:13];
// Populate label from array
cell.textLabel.text = titlesArray[indexPath.row];
if (indexPath.section == 0) {
UITextField* tf = nil;
switch ( indexPath.row ) {
case 0: {
tf = nameFieldTextField = [self makeTextField:self.name placeholder:@"John Appleseed"];
nameFieldTextField.tag = 1;
[cell addSubview:nameFieldTextField];
break ;
}
// Textfield dimensions
tf.frame = CGRectMake(120, 12, 170, 30);
// Workaround to dismiss keyboard when Done/Return is tapped
[tf addTarget:self action:@selector(textFieldFinished:) forControlEvents:UIControlEventEditingDidEndOnExit];
}
// Set the reuse identifier to a unique string, based on placement in table
// This ensures that the textField will retain its text
cell.reuseIdentifier = [NSString stringWithFormat:@"%i%i", indexPath.section, indexPath.row];
}
return cell;
}
// Textfield value changed, store the new value.
- (void)textFieldDidEndEditing:(UITextField *)textField {
//Section 1.
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
switch (textField.tag) {
case 1:
[defaults setObject:textField.text forKey:@"nameCellString"];
self.name = textField.text;
break;
default:
break;
}
[defaults synchronize];
}
编辑:更改为容纳更多单元格。
答案 2 :(得分:0)
我认为解决问题的最简单方法是为您的单元格创建一个新类(继承自UITableViewCell
)并添加新属性,如customerTextField (UITextField)
。在构造函数中添加新的文本字段但使用CGRectZero
。在方法layoutSubviews中,您将为文本字段指定CGRect
。
一般来说,这种方法会使您的UIViewController
更清晰(您将减少文本字段状态的检查次数)。
答案 3 :(得分:0)
您应该为tableDataSourceArray使用UIDictionary数组,如:
step1)
NSArray *tableDataSourceArray = [[NSArray alloc]init];
NSMutableDictionary *cellData = [[NSMutableDictionary alloc]init];
[cellData setValue:@"" forKey:@"Name"];
...//so on
[tableDataSourceArray addObject:cellData];
cellData = nil;
repeat step1 as number of records you have.
现在在
cellForRowAtIndexPath
:
nameFieldTextField.tag = indexPath.row; //To store index of dataSourceArray
nameFieldTextField.text = [[tableDataSourceArray objectAtIndex:indexPath.row] valueForKey:@"Name"];
最后在
textFieldDidEndEditing
:
NSMutableDictionary *cellDataDic = tableDataSourceArray objectAtIndex:textField.tag];
[cellDataDic setValue:textField.text forKey:@“Name”];
希望它会对你有所帮助。