iOS:Textfield委托,如何在表格视图中处理行移动之前自动结束编辑?

时间:2013-12-13 10:34:03

标签: ios uitableview uitextfield

在我的表格视图的编辑阶段,您可以编辑所有单元格中的UITextField并同时移动单元格。如果您更改某个文本字段的文本并立即将该文本字段或更好的包含该文本字段的单元格移动到另一个indexPath,则会出现一个小问题,因为该文本尚未保存。然后一切都搞砸了。

要解决这个问题,我基本上想在开始行移动之前自动调用textFieldDidEndEditing。这应该工作正常吗?但是,如何以编程方式正确结束文本域的编辑?通过辞职第一响应者?我该怎么做?

My two relevant functions:
-(void)textFieldDidEndEditing:(UITextField *)textField
{
    self.suspendAutomaticTrackingOfChangesInManagedObjectContext = YES;
    //Did End editing is always called first after ending the editing either by enter or by clicking the done button. So this method saves the newly entered text
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:textField.tag inSection:0];
    MainCategory *mainCategory = [self.fetchedResultsController objectAtIndexPath:indexPath];

    if(textField.text != mainCategory.name){
        mainCategory.name = textField.text;
    }

    self.activeField = nil;

    [self stopSuspendAutomaticTrackingOfChangesInManagedObjectContextWithDelay:0.3f];
}

- (void)tableView:(UITableView *)tableView
moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath
      toIndexPath:(NSIndexPath *)destinationIndexPath;
{
    // Process the row move. This means updating the data model to correct the item indices.

    //reordering has been defined in the CoreDataViewController so the
    //FetchedResultsController doesn't mess up the reordering since he would update
    //the fetched results permanently while reordering
    self.reordering = YES;

    //Makes only a mutable copy of the array, but NOT the objects (references) within
    NSMutableArray *fetchedResults = [[self.fetchedResultsController fetchedObjects] mutableCopy];

    // Grab the item we're moving
    NSManagedObject *resultToMove = [self.fetchedResultsController objectAtIndexPath:sourceIndexPath];

    // Remove the object we're moving from the array.
    [fetchedResults removeObject:resultToMove];
    // Now re-insert it at the destination.
    [fetchedResults insertObject:resultToMove atIndex:[destinationIndexPath row]];

    // All of the objects are now in their correct order. Update each
    // object's displayOrder field by iterating through the array.
    int i = 1;
    for (MainCategory *fetchedResult in fetchedResults)
    {
        fetchedResult.position = [NSNumber numberWithInt:i++];
    }

    // Save
    NSError *error = nil;
    [self.budgetDatabase.managedObjectContext save:&error];

    // re-do the fetch so that the underlying cache of objects will be sorted
    // correctly
    [self.fetchedResultsController performFetch:&error];
    [self.tableView reloadData];

    self.reordering = NO;
}

编辑:我的新代码仍无效:

- (void)tableView:(UITableView *)tableView
moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath
      toIndexPath:(NSIndexPath *)destinationIndexPath;
{

    if(self.activeField){
        [self saveTextFieldEntry:self.activeField];
    }
    // Process the row move. This means updating the data model to correct the item indices.

    //reordering has been defined in the CoreDataViewController so the
    //FetchedResultsController doesn't mess up the reordering since he would update
    //the fetched results permanently while reordering
    self.reordering = YES;

    //Makes only a mutable copy of the array, but NOT the objects (references) within
    NSMutableArray *fetchedResults = [[self.fetchedResultsController fetchedObjects] mutableCopy];

    // Grab the item we're moving
    NSManagedObject *resultToMove = [self.fetchedResultsController objectAtIndexPath:sourceIndexPath];

    // Remove the object we're moving from the array.
    [fetchedResults removeObject:resultToMove];
    // Now re-insert it at the destination.
    [fetchedResults insertObject:resultToMove atIndex:[destinationIndexPath row]];

    // All of the objects are now in their correct order. Update each
    // object's displayOrder field by iterating through the array.
    int i = 1;
    for (MainCategory *fetchedResult in fetchedResults)
    {
        fetchedResult.position = [NSNumber numberWithInt:i++];
    }

    // Save
    NSError *error = nil;
    [self.budgetDatabase.managedObjectContext save:&error];

    // re-do the fetch so that the underlying cache of objects will be sorted
    // correctly
    [self.fetchedResultsController performFetch:&error];
    [self.tableView reloadData];

    self.reordering = NO;
}

-(void)textFieldDidBeginEditing:(UITextField *)textField
{
    self.activeField = textField;
}

-(void)textFieldDidEndEditing:(UITextField *)textField
{
//    self.suspendAutomaticTrackingOfChangesInManagedObjectContext = YES;
    //Did End editing is always called first after ending the editing either by enter or by clicking the done button. So this method saves the newly entered text
//    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:textField.tag inSection:0];
//    MainCategory *mainCategory = [self.fetchedResultsController objectAtIndexPath:indexPath];
//
//    if(textField.text != mainCategory.name){
//        mainCategory.name = textField.text;
//    }
//    
//    self.activeField = nil;

    [self saveTextFieldEntry:textField];

//    [self stopSuspendAutomaticTrackingOfChangesInManagedObjectContextWithDelay:0.3f];
}

- (void)saveTextFieldEntry:(UITextField *)textField
{
    self.suspendAutomaticTrackingOfChangesInManagedObjectContext = YES;
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:textField.tag inSection:0];
    MainCategory *mainCategory = [self.fetchedResultsController objectAtIndexPath:indexPath];

    if(textField.text != mainCategory.name){
        mainCategory.name = textField.text;
    }

    self.activeField = nil;

    [self stopSuspendAutomaticTrackingOfChangesInManagedObjectContextWithDelay:0.3f];
}

如何在行移动之前确定此保存过程已完成?也许这就是它不工作的原因,因为它比移动慢?!

3 个答案:

答案 0 :(得分:2)

您可以声明一个实例变量,例如:

UITextField * selectedTextField;

并将其更改为:

- (void)textFieldDidBeginEditing:(UITextField *)textField {
    selectedTextField = textField;
}

- (void)textFieldDidEndEditing:(UITextField *)textField {
    selectedTextField = nil;
}

无论您何时执行需要重新启动活动文本字段的操作,请添加:

if (selectedTextField && [selectedTextField isFirstResponder]) 
      [selectedTextField resignFirstResponder];

答案 1 :(得分:1)

首先为tableView的每个单元格中创建的每个textField分配一个唯一的标记值,然后使用方法 textFieldDidBeginEditing:将变量的值与文本值一起存储在变量中,当用户移动到next textField或fires textFieldDidEndEditing:方法检查textField.tag值是否与已存储的值匹配。如果匹配,则使用已存储在..

中的标记值更新您想要的内容

答案 2 :(得分:1)

将当前的textField保存在UITextFieldDelegate

的属性中
- (void)textFieldDidBeginEditing:(UITextField *)textField; 

并在你的行中移动函数对保存的textField进行无效调用。