editableCellDidEndOnExit执行得太晚了

时间:2011-04-21 00:34:16

标签: objective-c cocoa-touch core-data uitableview

我有一个用于编辑tableviewcells的详细控制器。当我完成一个单元格的编辑时,我使用editableCellDidEndOnExit将相应的更改排入我的数据库。当焦点从一个单元格移动到另一个单元格时,这可以正常工但是,当用户按下导航栏中的“保存”按钮时,焦点将从正在编辑的单元格转到“保存”按钮。因此,首先执行按Save按钮调用的操作,然后执行editableCellDidEndOnExit操作。

问题在于,当按下保存按钮时,我将队列更改(使用NSManagedObject:save :)更改为数据库。只有在此之后调用editableCellDidEndOnExit并且对最后一个单元格的更改才会排队。它没有被提交(保存)。

我该怎么做才能确保在保存之前进行最后一次单元格编辑?

我想我可以使用editableCellDidBeginEditing存储指向正在编辑的单元格的指针,然后在按下保存按钮时引用该值。有人可以提供其他想法吗?

以下是一些相关代码:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.navigationItem.title = @"Client Info";
        self.navigationItem.rightBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(doneSave)] autorelease];
        self.navigationItem.leftBarButtonItem = [[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancel)] autorelease];
        keyboardShown = NO;
        currentCell = nil;

        dataInterface = [DataInterfaceObject alloc]; // a singleton
        clientMO = [[Client alloc] init ];
    }
    return self;
}


// queue the change
- (void)editableCellDidEndEditing:(EditableCell *)cell {
    [clientMO setValue:cell.textField.text forKey:cell.keyName];  
};


// commit (save) the changes
- (void) doneSave {
    [dataInterface commitChangesAndNotify:@"clientUpdate"];
    [self.navigationController popViewControllerAnimated:YES];
}

-(void) commitChangesAndNotify:(NSString *)notification{
    if([self.managedObjectContext hasChanges])
    {
        [[NSNotificationCenter defaultCenter] postNotificationName:notification object:nil];  // tell everybody that needs to know about this change (so they can update their view data sources)
        [self.managedObjectContext save:nil];
    }     
}

1 个答案:

答案 0 :(得分:0)

我尝试了几个方法来解决这个问题,但在每种情况下, editableCellDidEndEditing:cell:的事件总是会在提交更改后处理。我尝试更改代码的顺序,看看是否可以更快地处理事件。我尝试用两种方法替换方法 doneSave ,其中第一种方法 willSaveOnExit ,将事件排队以调用第二种方法 didSaveOnExit 。我们的想法是将提交操作放入 didSaveOnExit ,并将事件排在 editableCellDidEndEditing 之后。

不幸的是,我发现在弹出视图控制器并显示上一个视图之前,从未生成调用 editableCellDidEndEditing:cell 的事件。因此,尝试重新排列事件队列毫无意义。我没有耐心试图找到解决方法,因为我想不出一种方法可以与前一个视图出现的详细视图控制器进行通信。 (我可能会想出来,但是,当时,我并没有在那个方向上感觉太有创意。)

毕竟,以上都不是必需的。

以下是我最终要做的事情:

(这与我在问题中的建议非常相似)

我在tableviewcontroller中创建了一个名为currentCell的ivar,我在方法 editableCellDidBeginEditing:cell:中设置了指向正在进行编辑的单元格。

currentCell在 viewDidAppear

中初始化为nil

我更改了此代码(请参阅原始问题),将代码包装在条件

- (void)editableCellDidEndEditing:(EditableCell *)cell {
    if (currentCell){
        [clientMO setValue:currentCell.textField.text forKey:currentCell.keyName]; // update the value 
    }
}

我将Save按钮处理程序方法更改为此

- (void) doneSave {
    [self editableCellDidEndEditing:currentCell];
    currentCell = nil;
    [dataInterface commitChangesAndNotify:@"clientUpdate"];    
    [self.navigationController popViewControllerAnimated:YES];
}

(将前两行添加到我的问题中的版本)

现在,我知道如果按下了保存按钮,那么用户就完成了编辑,所以我想在提交更改之前最后一次调用 editableCellDidEndEditing:cell: 。但是由于我的代码是调用(而不是事件处理程序),我必须提供单元格指针,这是我在单元格编辑开始时获得的,并且已经放入了currentCell。

然后我将currentCell设置为nil,表示不再有当前单元格。现在,请记住,我说在上一个视图出现之前,仍会有一个排队等待 editableCellDidEndEditing:cell:的事件。当该方法执行时,currentCell(!= nil)的条件测试将通过,并绕过代码。

所以最后看来,即使对 editableCellDidEndEditing:cell:的多余调用仍在发生,一切都按照正确的顺序运行。

我现在很高兴。