Использование протокола / делегата для изменения UITableViewCell из другого класса - PullRequest
0 голосов
/ 31 октября 2011

Ну, я действительно застрял со следующей проблемой:

У меня есть 2 класса: NoticeViewAddController (назовем его vc1) и NoticeViewAddControllerAddNotice (назовем его vc2).

vc1 вызывает vc2. В vc2 есть UITextView, где пользователь может добавить текст и нажать «Сохранить» (кнопка «Сохранить» сохраняет его в Core Data, но это не главное). Когда я хочу открыть vc2 и снова открыть vc1, я хочу, чтобы его UITableViewCell получил текст из UITextView vc2 (перезагрузка UITableView также необходима, не так ли?).

Из того, что я читал до сих пор, удаление и протокол кажутся наиболее элегантным способом, но я действительно не понимаю.

  1. Должен ли vc1 иметь этот протокол?
  2. Какой метод должен быть в этом протоколе?
  3. Как я могу затем изменить cell.textLabel.text для indexPath.section == 0 и indexPath.row == 0).

Буду признателен за любую помощь!

Ответы [ 2 ]

0 голосов
/ 02 ноября 2011

Это довольно просто, если вы используете NSFetchedResultsController для своего табличного представления. С этим вы можете реализовать методы протокола NSFetchedResultsControllerDelegate в вашем контроллере представления vc1:

– controllerWillChangeContent:
– controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:
– controller:didChangeSection:atIndex:forChangeType:
– controllerDidChangeContent:

Таким образом, когда вы сохраняете изменения в вашем managedObjectContext в viewcontroller vc2, автоматически генерируется событие hasChanges, уведомляющее fetchedResultsController, и fetchedResultsController выполняет эти методы делегата. Ваша таблица будет автоматически обновляться с изменениями, используя код в ваших методах делегата. В вашем случае, я думаю, вы сосредоточены на методе controller:didChangeObject:atIndexPath:forChangeType:newIndexPath:, где тип изменения - NSFetchedResultsChangeUpdate.

Если это тип обновления, вы можете просто настроить ячейку на indexPath так же, как вы делаете это в методе tableView insertRowsAtIndexPaths:withRowAnimation:. Конечно, в этом случае ячейка уже находится в таблице, поэтому вы не вставляете ее, а переконфигурируете.

Вы будете заключать в скобки методы делегата с помощью 1controllerWillChangeContent: and 1controllerDidChangeContent:, содержащего вызовы [tableView beginUpdates]; и [tableView endUpdates] соответственно (где tableView заменяется ссылкой на ваш объект tableView). Они сохраняют радость fetchedResultsController и tableView во время внесения изменений, и вы не получите никаких ошибок, связанных с их несинхронизацией. (Вероятно, это не большая проблема, если вы меняете только содержимое ячейки.)

Я найду вам пример, когда вернусь в свой офис и выложу его здесь. Я сделал это в выходные на проекте, с которым я работаю, и это решило много проблем.

0 голосов
/ 02 ноября 2011

Я думаю, что протокол будет слишком много в этом случае. Просто продолжайте реализацию делегата, установив свойство ivar & в vc2:

@class vc1;

interface vc2 {
    vc1* delegate
...
}
@property (nonatomic, assign) vc1* delegate;

Определите его как назначить, и тогда вам не нужно управлять памятью. В vc1 установите делегат перед вызовом vc2:

[vc2_instance setDelegate:self];

В vc1 вам нужен метод обратного вызова для уведомления о результате:

- (void) notify:(NSString* thetext);

Метод notify является идеальным местом для перезагрузки табличного представления. Затем вы вызываете его в vc2 как раз перед тем, как вывести его:

[delegate notify:textlabel.text];

Хоп, это помогает.

...