核心数据的表视图上的奇怪行为 [英] Strange behaviour on table view with core data

查看:124
本文介绍了核心数据的表视图上的奇怪行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一步一步我正在推进创建我的第一个iOS应用程序。现在我在一个表视图控制器上遇到一个奇怪的行为,我不能解决,我一直在寻找的原因为几个小时。这是情况:

step by step I am advancing creating my first iOS app. Now I am experiencing a strange behaviour on a table view controller which I am not able to solve and I have been searching for the reason for hours. THis is the scenario:


  1. 使用核心数据的简单iOS应用程序。


  2. 一个视图控制器(EditViewController)用于更新对象的一个​​核心数据实体对象。

  1. Simple iOS app using core data.
  2. Table view controller to show one core data entity objects.
  3. One view controller (AddViewController) to enter several attributes values.
  4. One view controller (EditViewController) to update the object values (after row selection on the table view controller.

为了使问题清晰起见,我只考虑三个属性,'thingName','urgent'和'color',所有字符串属性。每行显示一个字符串(thingName),一个图像作为颜色属性的图标,另一个图像作为紧急属性的图标
应用程序进程从一个空白表开始,在按下添加按钮后,应用程序显示AddViewController视图,即具有文本字段(thingName)的视图,切换标记对象为紧急/非紧急和一组彩色按钮在引入thingName之后,选择紧急或不紧急的对象,并选择一个颜色按钮,用户点击保存按钮,然后点击返回按钮返回到表格视图控制器。一切正常工作。出现一个包含thingName文本的新行为cell.text,表示对象被标记为紧急的图标,以及来自用户选择的颜色的彩色铅笔。
然后,如果用户想要更改thingName文本/紧急或不紧急/颜色,选择对象行,应用程序显示editViewController。如果用户更改文本并保存后,更新的文本也会显示在表格视图上,这意味着应用程序已存储更改。如果用户更改紧急状态,从不紧急到紧急,保存并返回到表视图后,紧急图标会按预期显示,但从紧急更改为不紧急后,保存并返回表视图,不应出现的紧急图标,确实出现。为了检查问题,我在editviewcontroller上包括一个文本字段(urgentTextField)来显示紧急属性的内容,并且它从开关状态响应变化很好。这意味着,如果用户将开关设置为没有紧急,urgentTextField显示非紧急,如果用户设置切换到紧急,urgentTextField显示紧急。
示例:

To make the question clear enough, I will only take into account three of the attributes, 'thingName' , 'urgent' and 'color', all string attributes. Every row shows a string (thingName), an image as icon for the color attribute and another image as icon for the urgent attribute. The app process begin with a blank table, after pressing the Add button, the app shows the AddViewController view, that is a view with a text field (thingName), a switch to mark the object as urgent/not urgent and a group of colored buttons to assign a color dependency to the object. After introducing the thingName, selecting the object as urgent or not urgent, and selecting one of the colour buttons, the user taps on the save button and then to the back button to go back to the table view controller. Everything works as expected. A new row appears containing the thingName text as cell.text, the icon representing that the object was marked as urgent and a color pencil from the color selected by the user. Then, if the user wants to change the thingName text / urgent or not urgent / colour, selecting the object row, the app shows the editViewController. If the user changes the text and after saving, the updated text is also shown on the tableview, which means that the app has stored the changes. If the user changes the urgent state, from not urgent to urgent, after saving and going back to the table view, the urgent icon appears as expected, but after changing from urgent to not urgent, saving and going back to the table view, the urgent icon that shouldn't appear, does appear. To check the issue I have included a text field (urgentTextField) on the editviewcontroller to show the content of the urgent attribute, and it changes fine in response from the switch state. That means, if the user sets the switch to no urgent, the urgentTextField shows 'Not urgent', if the user sets the switch to urgent, the urgentTextField shows 'Urgent'. Sample case:

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

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

In this case, the row shows the expected text 'test'. but the icon is not responding as expected, then the urgent icon is shown.... To make it easier, this is the code:

RootViewController(table view controller):

RootViewController (table view controller):

- (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的代码:

And this is the code for 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.
}

请告诉我是否需要更多信息或代码来检测问题,我不能找到。
谢谢

Please, tell me if you need further information or code to detect where is the problem that I am not able to find. Thank you

推荐答案

您的问题似乎在 configureCell:方法。您不会考虑细胞再利用。您配置的单元可能需要使用之前,可能以前有紧急状态。

Your problem appears to be in the configureCell: method. You are not taking cell reuse into account. The cell you are configuring could have need used before and could have had an urgent status previously.

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

Your code only deals with the situation where the cell is urgent, in which case it adds a subview. There are two problems with this approach:


  1. 重复使用的单元格将每次都添加子视图 - 因此在顶部可能有许多紧急视图。该单元格应该只添加一次,并将其保存在属性

  2. 必须添加代码以配置该单元时不是紧急(通常, code>如果之后的 else )。这将隐藏紧急图标。

  1. A reused cell will have the subview added every time - so there could be many urgent views on top of each other. The cell should only ever add this once and keep it in a property
  2. Code must be added to configure the cell when it is not urgent (usually, an else after the if). This would hide the urgent icon.

这篇关于核心数据的表视图上的奇怪行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆