具有核心数据的表视图的奇怪行为

一步一步我正在推进创build我的第一个iOS应用程序。 现在我正在经历一个表格视图控制器上的一个奇怪的行为,我无法解决,我一直在寻找几个小时的原因。 这是情景:

  1. 简单的iOS应用使用核心数据。
  2. 表视图控制器显示一个核心数据实体对象。
  3. 一个视图控制器(AddViewController)input多个属性值。
  4. 一个视图控制器(EditViewController)更新对象值(在视图控制器上的行select之后)。

为了使问题清楚,我只考虑三个属性,'thingName','urgent'和'color',所有的string属性。 每行显示一个string(thingName),一个图像作为color属性的图标,另一个图像作为紧急属性的图标。 应用程序进程以空白表格开始,按下Addbutton后,应用程序显示AddViewController视图,即带有文本字段(thingName)的视图,将对象标记为紧急/不紧急的开关以及一组彩色button为对象分配颜色依赖关系。 在介绍了thingName后,select对象为紧急或不紧急,并select其中一个颜色button,用户点击保存button,然后到后退button返回到表视图控制器。 一切都按预期工作。 出现一个新行,其中包含thingName文本为cell.text,表示该对象被标记为紧急的图标以及用户select的颜色的彩色铅笔。 然后,如果用户想要更改thingName文本/紧急或不紧急/颜色,select对象行,应用程序显示editViewController。 如果用户改变了文本,保存后,更新的文本也显示在tableview,这意味着应用程序已经存储的变化。 如果用户将紧急状态从非紧急状态改变为紧急状态,则在保存并返回到表视图后,紧急图标如预期的那样出现,但是在从紧急状态变为非紧急状态后,保存并返回到表视图,不应该出现的紧急图标,确实出现。 为了检查这个问题,我在editviewcontroller中join了一个文本字段(urgentTextField)来显示紧急属性的内容,并且在开关状态的响应中变化很好。 这意味着,如果用户将开关设置为不紧急,那么urgentTextField显示“不紧急”,如果用户将开关设置为紧急,那么urgentTextField显示“紧急”。 示例:

thingName = @"test"; urgentTextField.text=@"Not urgent"; 

在这种情况下,该行显示预期的文本“testing”。 但图标没有按预期做出响应,那么显示紧急图标….为了更容易,这是代码:

RootViewController(表视图控制器):

 - (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath { NSManagedObject *managedObject = [fetchedResultsController objectAtIndexPath:indexPath]; NSString *colorValue = [[managedObject valueForKey:@"color"] description]; NSString *isUrgent = [[managedObject valueForKey:@"urgent"]description]; [[cell textLabel] setText:[[managedObject valueForKey:@"thingName"] description]]; NSString *myString = [NSString stringWithFormat:@"%@",[[managedObject valueForKey:@"todoYear"] description]]; //color pencil if ([hasColorValue isEqual:@"Si color"]){ UIButton *colorButton = [[UIButton alloc]initWithFrame:CGRectMake(308, 5, 10, 40)]; [colorButton setImage:[UIImage imageNamed:colorValue]forState:UIControlStateNormal]; [cell addSubview:colorButton]; } //urgent if ([isUrgent isEqual:@"Urgent"]){ UIButton *urgentButton = [[UIButton alloc]initWithFrame:CGRectMake(71, 27, 18, 18)]; [urgentButton setImage:[UIImage imageNamed:@"urgent-3"]forState:UIControlStateNormal]; [cell addSubview:urgentButton]; } ../.. 

这是EditViewController的代码:

 - (IBAction)SaveButtonAction:(id)sender { AppDelegate* appDelegate = [AppDelegate sharedAppDelegate]; NSManagedObjectContext* context = appDelegate.managedObjectContext; [selectedObject setValue:ToDoTextField.text forKey:@"thingName"]; NSString *valorUrgent = urgentTextField.text; [selectedObject setValue:valorUrgent forKey:@"urgent"]; NSError *error; if(! [context save:&error]) { NSLog(@"Whoopw,couldn't save:%@", [error localizedDescription]); } } - (void)viewDidLoad { colorImagen.image = [UIImage imageNamed:nil]; [ToDoTextField becomeFirstResponder]; //recogiendo datos de selectedobject; ToDoTextField.text = [[selectedObject valueForKey:@"thingName"]description]; colorTextField.text = [[selectedObject valueForKey:@"color"]description]; NSString *imageName = colorTextField.text; colorImagen.image = [UIImage imageNamed:imageName]; NSString *urgentValue = [[selectedObject valueForKey:@"urgent"]description]; urgentTextField.text = urgentValue; if ([urgentValue isEqual:@"Urgent"]){ [urgentSwitch setOn:YES animated:YES]; urgentImage.image=[UIImage imageNamed:@"urgent-3"]; } if ([urgentValue isEqual:@"Not urgent"]){ [urgentSwitch setOn:NO animated:YES]; urgentImage.image=[UIImage imageNamed:nil]; } [ToDoTextField addTarget:self action:@selector(textFieldDidChange) forControlEvents:UIControlEventEditingChanged]; [super viewDidLoad]; // Do any additional setup after loading the view from its nib. } 

请告诉我,如果您需要进一步的信息或代码来检测我无法find的问题在哪里。 谢谢

你的问题似乎在configureCell:方法。 你没有考虑到细胞再利用。 您正在configuration的单元格可能需要使用之前,可能以前有一个紧急状态。

你的代码只处理单元格紧急的情况,在这种情况下,它添加了一个子视图。 这种方法有两个问题:

  1. 重复使用的单元格每次都会添加子视图 – 因此可能会有很多紧急的视图在彼此之上。 单元格应该只添加一次,并将其保留在属性中
  2. 必须添加代码以便在紧急时configuration单元格(通常是else之后的else单元格)。 这会隐藏紧急图标。

我注意到的第一个问题是你必须添加代码

 [super viewDidLoad]; // Do any additional setup after loading the view from its nib. 

不在之前。 这将保证你的观点至less被加载。

其次,从所有你的string文字conststring这样做,并在任何地方使用它

 static NSString * const kUrgentState = @"Urgent"; 

还有一个常见的提示:添加NSLog(…); 或者在debugging中testingvariables的值来定位问题,导致现在真的需要很多代码,但是还不足以发现问题。 findvariables的值出错的时刻,然后解决你的问题