Лучшая практика для отправки «перезагрузки» сигнала в UITableView из одного представления в другое - PullRequest
3 голосов
/ 11 января 2012

Моя цель - уведомить UITableView о необходимости обновлять себя каждый раз, когда изменяются некоторые конфигурации. Проблема заключается в том, что представление конфигурации «не» в том же представлении, которое генерирует сигнал. (Да, я использовал приложение с вкладками.)

В настоящее время я использую своего рода глобальную переменную в AppDelegate для обнаружения изменений в одном представлении и выполняю проверку в другом представлении. Это хорошо, но код не читается, так как он тесно связан. Есть ли элегантный способ сделать это? Я что-то упускаю в этой среде программирования?

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

Ответы [ 4 ]

2 голосов
/ 11 января 2012

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

Например, скажем, одна вкладка показывает список автомобилей в UITableViewController, и у вас есть другое представление, позволяющее пользователю добавить новую машину в список. Вы можете позволить UITableViewController

  • Принять протокол AddCarViewController
  • Установить себя в качестве делегата для протокола AddCarViewController
  • Реализовать свой метод протокола
  • Выполнить метод протокола при получении сообщения

Затем вы можете разрешить AddCarViewController

  • Создать протокол
  • Объявление ссылки на объект. Делегат с методами получения и установки.
  • Определите метод по этому протоколу
  • Сообщить делегату о выполнении действия Сохранить

Посмотрите на следующий пример кода для вашего UITableViewController

@interface ViewController : UITableViewController <AddCarViewControllerDelegate>

             :
             :

// The addCar: method is invoked when the user taps the Add button created at run time.
- (void)addCar:(id)sender
{
// Perform the segue named ShowAddCar
[self performSegueWithIdentifier:@"ShowAddCar" sender:self];
}

             :
             :

// This method is called by the system whenever you invoke the method     performSegueWithIdentifier:sender:
// You never call this method. It is invoked by the system.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    NSString *segueIdentifier = [segue identifier];

    if ([segueIdentifier isEqualToString:@"ShowAddCar"]) {

        // Obtain the object reference of the destination view controller
        AddCarViewController *addCarViewController = [segue destinationViewController];

        // Under the Delegation Design Pattern, set the addCarViewController's delegate to be self
        addCarViewController.delegate = self;

        // Instantiate a Save button to invoke the save: method when tapped
        UIBarButtonItem *saveButton = [[UIBarButtonItem alloc]
                                       initWithBarButtonSystemItem:UIBarButtonSystemItemSave
                                       target:addCarViewController action:@selector(save:)];

        // Set up the Save custom button on the right of the navigation bar
        addCarViewController.navigationItem.rightBarButtonItem = saveButton;

    }

}

                 :
                 :


- (void)addCarViewController:(AddCarViewController *)controller didFinishWithSave:    (BOOL)save {
                 :
                 :
}

Пример кода для AddCarViewController находится здесь

@protocol AddCarViewControllerDelegate;

@interface AddCarViewController : UIViewController

@property (nonatomic, strong) IBOutlet UITextField *carMake;
@property (nonatomic, strong) IBOutlet UITextField *CarName;
@property (nonatomic, assign) id <AddCarViewControllerDelegate> delegate;

// The keyboardDone: method is invoked when the user taps Done on the keyboard
- (IBAction)keyboardDone:(id)sender;

// The save: method is invoked when the user taps the Save button created at run time.
- (void)save:(id)sender;

@end

/*
 The Protocol must be specified after the Interface specification is ended.
 Guidelines:
 - Create a protocol name as ClassNameDelegate as we did above.
 - Create a protocol method name starting with the name of the class defining the protocol.
 - Make the first method parameter to be the object reference of the caller as we did below.
 */
@protocol AddCarViewControllerDelegate
- (void)addCarViewController:(AddCarViewController *)controller didFinishWithSave:(BOOL)save;
@end
2 голосов
/ 11 января 2012

Я бы использовал KVO (Key Value Observing), чтобы отслеживать, когда он меняется:

 - (void)viewDidLoad {
      [super viewDidLoad];  

      // Note that you can use the options to get the new value passed when it
      // changes if you want to update immediately.
      [configurationObject addObserver:self forKeyPath:@"configurationItem" options:0 context:nil];
 }

 - (void)viewDidUnload {
      [super viewDidUnload];
      [configurationObject removeObserver:self forKeyPath:@"configurationItem"];
 }

 // Note that I would refresh in viewWillAppear instead of viewDidAppear
 - (void)viewWillAppear:(BOOL)animated {
      [super viewWillAppear:animated];
      if (self.needToRefreshData == YES) {
           [self.tableView refreshData];
      }
 }

 - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
      if (keyPath isEqualToString:@"configurationItem") {
           [self.needToRefreshData = YES];
      }
 }
1 голос
/ 11 января 2012

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

Apple имеет некоторый шаблонный код для обработки обновлений

1 голос
/ 11 января 2012

Один из подходов состоит в том, чтобы иметь некоторый общий класс (возможно, синглтон, какой тип делегата приложения), который отслеживает вашу модель, когда настройки viewController обнаруживают изменения, они могут пометить модель как измененную, а затем, когда представлениена просмотр приходит вопрос, т. е. вызывается viewDidAppear, он может запросить модель, чтобы узнать, был ли установлен измененный флаг, если он установлен, то вы знаете, что нужно перезагрузить табличное представление, в противном случае вы не ...

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

надеюсь, это поможет

...