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

时间:2013-12-26 08:22:24

标签: ios objective-c core-data

一步一步我推进创建我的第一个iOS应用程序。现在我在桌面视图控制器上遇到一个奇怪的行为,我无法解决这个问题,而且我一直在寻找几个小时的原因。这就是场景:

  1. 使用核心数据的简单iOS应用。
  2. 表视图控制器,用于显示一个核心数据实体对象。
  3. 一个视图控制器(AddViewController),用于输入多个属性值。
  4. 一个视图控制器(EditViewController)来更新对象值(在表视图控制器上选择行之后。
  5. 为了使问题足够清楚,我将只考虑三个属性,'thingName','urgent'和'color',所有字符串属性。每行显示一个字符串(thingName),一个图像作为颜色属性的图标,另一个图像作为紧急属性的图标。 应用程序进程以空白表开头,按下“添加”按钮后,应用程序显示AddViewController视图,即带有文本字段的视图(thingName),用于将对象标记为紧急/非紧急的开关以及一组彩色用于为对象指定颜色依赖关系的按钮。在引入thingName,选择紧急或非紧急对象,并选择其中一个颜色按钮后,用户点击保存按钮,然后点击后退按钮返回到表视图控制器。一切都按预期工作。将出现一个新行,其中包含thingName文本作为cell.text,表示该对象被标记为紧急的图标以及来自用户所选颜色的彩色铅笔。 然后,如果用户想要更改thingName文本/紧急或不紧急/颜色,选择对象行,该应用程序将显示editViewController。如果用户更改文本并在保存后,更新的文本也会显示在tableview上,这意味着应用程序已存储更改。如果用户将紧急状态从紧急状态更改为紧急状态,则在保存并返回到表格视图后,紧急图标将按预期显示,但在从紧急状态变为非紧急状态后,保存并返回到表格视图,确实出现了不应出现的紧急图标。为了检查问题,我在editviewcontroller上包含了一个文本字段(urgentTextField)来显示紧急属性的内容,并且它在切换状态的响应中变化很好。这意味着,如果用户将开关设置为不紧急,则urgentTextField显示“Not urgent”,如果用户将开关设置为“紧急”,则urgentTextField显示“紧急”。 示例案例:

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

    在这种情况下,该行显示预期的文本'test'。但图标没有按预期响应,然后显示紧急图标.... 为了更容易,这是代码:

    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.
    }
    

    如果您需要更多信息或代码来检测我无法找到的问题,请告诉我。 谢谢

2 个答案:

答案 0 :(得分:3)

您的问题似乎出现在configureCell:方法中。您没有考虑细胞再利用。您之前可能需要使用您正在配置的单元,并且之前可能已经处于紧急状态。

您的代码仅处理单元格紧急的情况,在这种情况下,它会添加子视图。这种方法存在两个问题:

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

答案 1 :(得分:0)

我注意到代码的第一个问题是您必须在

之后添加代码
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
不是在它之前。它将保证至少加载您的视图。

其次,从所有字符串文字中获取这样的const字符串,并在任何地方使用它

static NSString * const kUrgentState = @"Urgent";

还有一个常见的提示:添加NSLog(...);或者在调试中测试变量的值以本地化问题,因为现在它确实需要很多代码,但仍然不足以找到问题。 找到变量值出错的时刻然后修复你的问题