editableCellDidEndOnExit выполняется слишком поздно - PullRequest
0 голосов
/ 21 апреля 2011

У меня есть детальный контроллер, настроенный для редактирования ячеек таблицы.Когда я заканчиваю редактировать ячейку, я использую editableCellDidEndOnExit, чтобы поставить в очередь соответствующее изменение в моей базе данных.Это прекрасно работает, когда фокус переходит от одной ячейки к другой.Однако, когда пользователь нажимает кнопку «Сохранить» на панели навигации, фокус переходит от редактируемой ячейки к кнопке «Сохранить».Как следствие, сначала выполняется действие, вызываемое нажатием кнопки «Сохранить», а затем выполняется действие 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 голосов
/ 22 апреля 2011

Я пытался решить эту проблему несколькими способами, но в каждом случае событие editableCellDidEndEditing: cell: всегда обрабатывалось после того, как изменения были зафиксированы. Я попытался изменить порядок своего кода, чтобы увидеть, смогу ли я обработать событие раньше. Я попытался заменить метод doneSave двумя методами, где первый метод, willSaveOnExit , ставит в очередь событие для вызова второго метода, didSaveOnExit . Идея заключалась в том, чтобы поместить операцию фиксации в didSaveOnExit и поместить событие в очередь после editableCellDidEndEditing .

К сожалению, я обнаружил, что событие, вызывающее editableCellDidEndEditing: ячейка , никогда не генерировалось, пока контроллер представления не был извлечен и не появилось предыдущее представление. Поэтому пытаться изменить порядок событий было бессмысленно. Я потерял терпение, пытаясь найти способ обойти это, потому что я не мог придумать, как связываться с контроллером детального представления о том, что появилось предыдущее представление. (Возможно, я мог бы это понять, но в то время я не чувствовал себя слишком творчески в этом направлении.)

Ничего из вышеперечисленного не было необходимо, в конце концов.

Вот что я в итоге сделал:

(что очень похоже на то, что я предложил в моем вопросе)

Я создал ivar в tableviewcontroller с именем currentCell, который я установил в методе editableCellDidBeginEditing: cell: , указывая на ячейку, где выполняется редактирование.

currentCell инициализируется нулем в viewDidAppear

Я изменил этот код (см. Мой вопрос для оригинала), оборачивая код в условное

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

Я изменил метод обработчика кнопки Сохранить на этот

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

(добавление первых двух строк к версии в моем вопросе)

Теперь я знаю, что если была нажата кнопка сохранения, то пользователь завершил редактирование, поэтому я хочу вызвать editableCellDidEndEditing: cell: в последний раз перед тем, как зафиксировать изменения . Но поскольку мой код вызывает (а не обработчик событий), я должен предоставить указатель ячейки, который я получил, когда началось редактирование ячейки, и поместил в currentCell.

Затем я установил currentCell на ноль, указывая, что больше нет текущей ячейки. Теперь, помните, что я сказал, что все еще будет событие, поставленное в очередь для editableCellDidEndEditing: cell: к моменту появления предыдущего представления. Когда этот метод выполняется, условный тест для currentCell (! = Nil) падает, и код обходит.

Итак, в конце концов, кажется, что все работает в правильном порядке, даже несмотря на то, что избыточный вызов editableCellDidEndEditing: cell: все еще происходит.

Сейчас я счастлив.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...