UITextViews在UITableView中被选中时未被清除

问题描述:

我正在实现一个带有文本视图的UITableView作为我的单元格的内容视图。当用户返回到屏幕UITextViews在UITableView中被选中时未被清除

- (BOOL)textFieldShouldReturn:(UITextField *)textField 
{ 
    if (textField == _textFieldOne){ 
     [settingsDictionary setObject: _textFieldOne.text forKey:@"EntryOneText"]; 
     [settingsDictionary stringValueForKey:@"textFieldOneValue"]; 
     [self postNotificationSettingsUpdate:settingsDictionary]; 
     didTestPostNotificationSettings = YES; 
} 

这些保存的值应显示在文本字段:当用户点击返回键

用户输入的数据被保存在设置字典,我已经用下面的代码完成:

//Set the value in the text fields from the settings dictionary 
    NSString *textFieldOneText = [self.settingsDictionary  stringValueForKey:@"RedZoneCarsPerManHrMin"]; 

    _textFieldOne.text = textFieldOneValue; 

到目前为止,一切似乎都按预期方式工作:文本输入被保存,并在文本字段中显示,当用户返回到屏幕。然而,如果TableView中的保持所述文本字段是选择(不文本字段本身),文本字段显示以下所示的行为:

enter image description here

似乎就好像文本字段显示新输入的条目以及上次保存的条目一样。

编辑 I'ved增加了更多的下面我的cellForRowAtIndexPath方法:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForSubscribedRedZoneAlertRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"RedZoneAlertCell"; 

    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]; 
    } 

    cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1]; 

    UISwitch *cellSwitch = nil; 

    NSNumber *position = enabledRedZoneAlertRows[indexPath.row]; 


switch (position.integerValue) { 
    case CarPerManHourRow: { 
     cell.textLabel.text = NSLocalizedString(@"Label", @"Label Row"); 
     cellSwitch = [[UISwitch alloc] init]; 
     cellSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:SwitchKey]; 
     cellSwitch.tag = SwitchTag; 
     [cellSwitch addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged]; 
     cell.accessoryView = cellSwitch; 

     if ([[self.settingsDictionary valueForKey:@"RedZoneCarsPerManHrOnOff"]isEqual: @"1"]){ 
      [cellSwitch setOn:YES]; 
     } 
     break; 
    } 
    case TextFieldRow: { 
     static NSString *CellIdentifier = @"ConfigCell"; 
     cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
     if (cell == nil) { 
      cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]; 
     [cell.contentView addSubview:_textFieldOne]; 
     [cell.contentView addSubview:_textFieldTwo]; 
     [cell.contentView addSubview:_spacingLabel]; 
     } 

     cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1]; 

     _textFieldOne = [[UITextField alloc]initWithFrame:CGRectMake(25, 0, 50, 30)]; 
     _textFieldTwo = [[UITextField alloc]initWithFrame:CGRectMake(100, 0, 50, 30)]; 

     _textFieldOne.delegate = self; 
     _textFieldTwo.delegate = self; 

     _textFieldOne.placeholder = @"Auto"; 
     _textFieldTwo.placeholder = @"Auto"; 
     [_textFieldOne setTextAlignment:NSTextAlignmentCenter]; 
     [_textFieldTwo setTextAlignment:NSTextAlignmentCenter]; 

     //Set the value in the text fields from the settings dictionary 
     NSString *textFieldOneText = [self.settingsDictionary stringValueForKey:@"RedZoneCarsPerManHrMin"]; 
     NSString *textFieldTwoText = [self.settingsDictionary stringValueForKey:@"RedZoneCarsPerManHrMax"]; 

     NSString *carsPerManHrMax = [self.settingsDictionary stringValueForKey:@"RedZoneCarsPerManHrMax"]; 
     NSString *carsPerManHrMax = [self.settingsDictionary stringValueForKey:@"RedZoneCarsPerManHrMax"]; 

     _textFieldOne.text = textFieldOneValue; 
     _textFieldTwo.text = textFieldTwoValue 

     _textFieldOne.backgroundColor = [UIColor whiteColor]; 
     _textFieldTwo.backgroundColor = [UIColor whiteColor]; 
     _textFieldOne.tintColor = [UIColor blackColor]; 
     _textFieldTwo.tintColor = [UIColor blackColor]; 

     [_textFieldOne.layer setCornerRadius:7.0f]; 
     [_textFieldTwo.layer setCornerRadius:7.0f]; 

     [_textFieldOne setKeyboardType:UIKeyboardTypeNumbersAndPunctuation]; 
     [_textFieldTwo setKeyboardType:UIKeyboardTypeNumbersAndPunctuation]; 

     _textFieldOne.returnKeyType = UIReturnKeyNext; 
     _textFieldTwo.returnKeyType = UIReturnKeyDone; 

     _spacingLabel = [[UILabel alloc] initWithFrame:CGRectMake(70, 0, 35, 30)]; 
     _spacingLabel.text = @"–"; 
     _spacingLabel.textColor = [UIColor colorWithRed:0.658 green:0.658 blue:0.658 alpha:1]; 
     [_spacingLabel setTextAlignment:NSTextAlignmentCenter]; 
     _spacingLabel.backgroundColor = [UIColor clearColor]; 

     //[cell.contentView addSubview:_textFieldOne]; 
     //[cell.contentView addSubview:_textFieldTwo]; 
     //[cell.contentView addSubview:_spacingLabel]; 

     break; 
    } 
    return cell; 
} 

编辑两个 下面是我在基于jherran的答案固定我的问题的尝试。不过,我仍然遇到同样的问题。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForSubscribedRedZoneAlertRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    static NSString *CellIdentifier = @"RedZoneAlertCell"; 

    UITableViewCell *cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]; 
    } 

    cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1]; 

    UISwitch *cellSwitch = nil; 

    NSNumber *position = enabledRedZoneAlertRows[indexPath.row]; 

    switch (position.integerValue) { 
     case CarPerManHourRow: { 
      cell.textLabel.text = NSLocalizedString(@"Label", @"Label Row"); 
      cellSwitch = [[UISwitch alloc] init]; 
      cellSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:SWSettingCarsPerManHour]; 
      cellSwitch.tag = SaveCarsPerManHourTag; 
      [cellSwitch addTarget:self action:@selector(switchChanged:) forControlEvents:UIControlEventValueChanged]; 
      cell.accessoryView = cellSwitch; 

      if ([[self.settingsDictionary valueForKey:@"RedZoneCarsPerManHrOnOff"]isEqual: @"1"]){ 
       [cellSwitch setOn:YES]; 
      } 
      break; 
     } 
     case CarsPerManHourConfigRow: { 

      static NSString *CellIdentifier = @"ConfigCell"; 
      cell = (UITableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
      if (cell == nil) { 
       cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier]; 

       cell.backgroundColor = [UIColor colorWithRed:0.922 green:0.937 blue:0.949 alpha:1]; 

       _carsPerManHourMinTextField = [[UITextField alloc]initWithFrame:CGRectMake(25, 0, 50, 30)]; 
       _carsPerManHourMaxTextField = [[UITextField alloc]initWithFrame:CGRectMake(100, 0, 50, 30)]; 

       _textFieldOne.delegate = self; 
       _textFieldTwo.delegate = self; 

       _textFieldOne.placeholder = @"Auto"; 
       _textFieldTwo.placeholder = @"Auto"; 
       [_textFieldOne setTextAlignment:NSTextAlignmentCenter]; 
       [_textFieldTwo setTextAlignment:NSTextAlignmentCenter]; 




       _textFieldOne.backgroundColor = [UIColor whiteColor]; 
       _textFieldTwo.backgroundColor = [UIColor whiteColor]; 
       _textFieldOne.tintColor = [UIColor blackColor]; 
       _textFieldTwo.tintColor = [UIColor blackColor]; 


       [_textFieldOne.layer setCornerRadius:7.0f]; 
       [_textFieldTwo.layer setCornerRadius:7.0f]; 

       [_textFieldOne setKeyboardType:UIKeyboardTypeNumbersAndPunctuation]; 
       [_carsPerManHourMaxTextField setKeyboardType:UIKeyboardTypeNumbersAndPunctuation]; 

       _textFieldOne.returnKeyType = UIReturnKeyNext; 
       _textFieldTwo.returnKeyType = UIReturnKeyDone; 

       _spacingLabel = [[UILabel alloc] initWithFrame:CGRectMake(70, 0, 35, 30)]; 
       _spacingLabel.text = @"–"; 
       _spacingLabel.textColor = [UIColor colorWithRed:0.658 green:0.658 blue:0.658 alpha:1]; 
       [_spacingLabel setTextAlignment:NSTextAlignmentCenter]; 
       _spacingLabel.backgroundColor = [UIColor clearColor]; 

       NSLog(@"%@", _textFieldOne.text); 
       NSLog(@"%@",_carsPerManHourMaxTextField.text); 

       [cell.contentView addSubview: _textFieldOne]; 
       [cell.contentView addSubview: _textFieldTwo]; 
       [cell.contentView addSubview:_spacingLabel]; 

       cell.tag = 1; 
      } 

      else { 
       _textFieldOne = (UITextField *)[cell.contentView viewWithTag:1]; 
       _textFieldTwo = (UITextField *)[cell.contentView viewWithTag:1]; 
       _spacingLabel = (UILabel *)[cell.contentView viewWithTag:1]; 
      } 

      NSString * _textFieldOne = [self.settingsDictionary stringValueForKey:@"RedZoneCarsPerManHrMin"]; 
      NSString *carsPerManHrMax = [self.settingsDictionary stringValueForKey:@"RedZoneCarsPerManHrMax"]; 

      _textFieldOne.text = carsPerManHrMin; 
      _textFieldTwo.text = carsPerManHrMax; 

如何修改我的代码以避免此行为发生?

+0

请向我们展示整个cellForRowAtIndexPathMethod。 – 2015-03-02 17:41:07

+0

嗨@EarlGrey,我在我的编辑中添加了大部分cellForRowAtIndexPathMethod。我无法添加整个方法,因为它很长(它们是表格视图特定部分中的单元格)。 – narner 2015-03-02 18:16:41

检查您的cellForRowAtIndexPath,因为单元格被重用,您可能未加载单元格属性。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    /* 
    * This is an important bit, it asks the table view if it has any available cells 
    * already created which it is not using (if they are offscreen), so that it can 
    * reuse them (saving the time of alloc/init/load from xib a new cell). 
    * The identifier is there to differentiate between different types of cells 
    * (you can display different types of cells in the same table view) 
    */ 

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MyIdentifier"]; 

    /* 
    * If the cell is nil it means no cell was available for reuse and that we should 
    * create a new one. 
    */ 
    UILabel *label; 
    if (cell == nil) { 

     /* 
     * Actually create a new cell (with an identifier so that it can be dequeued). 
     */ 

     cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MyIdentifier"] autorelease]; 

     label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)]; 
     cell.tag = 1; 
     [cell.contentView addSubview:label]; 

    } else { 

     label = (UILabel *)[cell.contentView viewWithTag:1]; 

    } 

    /* 
    * Now that we have a cell we can configure it to display the data corresponding to 
    * this row/section 
    */ 

    label.text = @"whatever"; 
} 

编辑:当你的电池出口和重复使用,您要添加视图([cell.contentView addSubview:_textFieldOne])每个细胞的再生时。

+0

啊,我很高兴看到你的编辑,这很有道理!换句话说,我只需要将我的textField添加到单元格的子视图中一次,对吗?我将如何实现? – narner 2015-03-02 19:25:23

+0

您必须在'cell == nil'时添加它。你在那里初始化单元格,并且它是子视图。就是这个方法。 – jherran 2015-03-02 19:30:13

+0

在我的答案中看到我全面的解决方案。 – 2015-03-02 19:31:20

好的,这是我怀疑的。每次将单元格从重用队列中取出时,都会创建一个新的textfield实例并将其添加到内容视图中。所以基本上内容视图堆积着新的文本框。 你应该做的是

1)有一个自定义单元格,使细胞负责其内部

2)只暴露的配置方法传递的唯一类原始文本细胞

3)当thr cell被重用时调用该配置方法。 4)保留对自定义单元格内文本字段的引用,以便随时更新文本值。当它在cellforrowatindexpath中回收时

+0

这使得什么是错的。恐怕我并不完全了解你的解决方案;你会介意多解释一下吗?我很抱歉! – narner 2015-03-02 19:35:50

+0

什么具体应该更详细? – 2015-03-02 20:46:17