Определить имя предыдущего UIView

Мне было интересно, если можно найти, какое представление вызвало следующую функцию

- (void)viewWillAppear:(BOOL)animated {
  //find here the name of the calling view
}

Есть ли способ найти, какой вид называется новым?

4 ответа

Решение

Само собой разумеется, "представления" не вызывают это, скорее iOS будет вызывать это, когда ваше представление появляется. И, к сожалению, это сложно, потому что вы можете получить viewWillAppear потому что какой-то другой контроллер представления представил это представление контроллера представления, или вы могли бы получить это, когда контроллер представления, представленный этим представлением, был отклонен или вытолкнут (в зависимости от модального или push).

Мы, вероятно, можем наметить все виды сложных и сложных способов решения этой проблемы, но мы, вероятно, должны сначала сделать шаг назад и спросить, зачем вам это нужно. Чего вы действительно пытаетесь достичь? Если вы просто пытаетесь координировать взаимодействие между контроллерами представления, есть гораздо лучшие способы сделать это (например, делегаты, настройка свойств контроллера представления и т. Д.).


Обновить:

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

Самый простой способ сделать это - использовать шаблон проектирования делегата, где ваш дочерний контроллер представления будет иметь delegate свойство, которое является указателем на ваш контроллер, который должен знать об изменении данных, и дочерний контроллер просто вызовет этот метод, когда данные изменятся. В немного более сложных сценариях вы можете комбинировать этот шаблон делегата с формальным протоколом делегата (так что дочернему контроллеру представления не нужно ничего знать о родительском контроллере, кроме факта, что он соответствует определенному протоколу), но некоторые Можно сказать, что в этом нет необходимости, когда вы просто общаетесь между двумя конкретными и хорошо известными контроллерами представления. См. Использование делегирования для связи с другими контроллерами в Руководстве по программированию View Controller.

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

В viewWillAppear прямо нет. Если он выдвинут на UINavigationController, вы можете получить viewControllers и получить предыдущий.

if (self.navigationController){
NSArray* viewControllers = self.navigationControllers.viewControllers;
UIViewController* lastViewController = [viewControllers objectAtIndex:([viewControllers count] - 1)];
NSLog(@"%@ is my last ViewController before navigationg to this ViewController", lastViewController);
}

Ты можешь использовать presentingViewController для этого, но проблема в том, что это вернет адрес памяти контроллера представления, а не имя указателя.

Одним из решений было бы назначить тег для свойства view текущего контроллера представления, а затем запросить этот тег во втором контроллере:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    NSLog(@"%i",[[[self presentingViewController] view] tag]);
}

В вашем первом контроллере представления:

[[self view] setTag:(someNSInteger)];

Хорошо, если вы используете навигационный контроллер, вы можете получить массив viewControllers, который выдвигается:

 NSArray *array =  self.navigationController.viewControllers;

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

- (void)viewWillAppear:(BOOL)animated {
  //find here the name of the calling view
  }

будет называться.

Другие вопросы по тегам