0

I have seen every post that is close to this question, and still not finding something useful. I have textFields in every cell that is being used as a form for the user to fill out. Everything with the cells works fine except when scrolling, the input in the textFields disappears when the cell scrolls off screen. I know this is because of dequeue. But there should be a way to save the data entered so that it doesn't disappear when scrolling or exiting the app. I also want to be able to take this info and email it as a PDF, or document. What is the best way to achieve this? The code below is an example of how I am generating my cells etc.

.h file

@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 file

@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"];

}
4

4 回答 4

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];
}

编辑:更改以容纳更多单元格。

于 2013-06-05T17:03:11.207 回答
1

There are actually two problems here, both of them being in your cellForRowAtIndexPath: implementation.

  • You are putting the text field into the cell, even if this cell is reused and already has a text field. Thus you are actually piling text field over text field, covering up the previously existing text field.

  • You are not putting the text back into the text field if there was already text in the text field for that row (index path).

In other words, the cells are (as you rightly say) reused, so it is up to you to take that fact into account. You must look at the state of the incoming cell, and reconfigure the cell accordingly.

于 2013-05-21T00:34:24.827 回答
0

我认为解决您的问题的最简单方法是为您的单元格创建一个新类(继承自UITableViewCell)并添加新属性,例如customerTextField (UITextField). 在构造函数中添加新的文本字段,但带有CGRectZero. 在方法 layoutSubviews 中,您将为CGRect您的文本字段分配。一般来说,这种方法会使您UIViewController更清洁(您将减少对文本字段状态的检查次数)。

于 2013-06-11T09:00:31.797 回答
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"];

希望它会帮助你。

于 2013-06-11T11:05:26.920 回答