Я просто впервые погружаюсь в разработку под iOS, и одна из первых вещей, которые мне нужно было сделать, - реализовать собственный контроллер представления контейнера - назовем его SideBarViewController
- который меняет какой из нескольких возможных дочерних контроллеров представления это показывает, почти так же, как стандартный контроллер панели вкладок. (Это в значительной степени контроллер панели вкладок, но со скрываемым боковым меню вместо панели вкладок.)
Согласно инструкциям в документации Apple, я вызываю addChildViewController
всякий раз, когда добавляю дочерний ViewController в свой контейнер. Мой код для замены текущего дочернего контроллера представления, показанного SideBarViewController
выглядит следующим образом:
- (void)showViewController:(UIViewController *)newViewController {
UIViewController* oldViewController = [self.childViewControllers
objectAtIndex:0];
[oldViewController removeFromParentViewController];
[oldViewController.view removeFromSuperview];
newViewController.view.frame = CGRectMake(
0, 0, self.view.frame.size.width, self.view.frame.size.height
);
[self addChildViewController: newViewController];
[self.view addSubview: newViewController.view];
}
Затем я начал пытаться выяснить, что именно здесь делает addChildViewController
, и понял, что понятия не имею. Помимо вставки нового ViewController
в массив .childViewControllers
, он, похоже, ни на что не влияет. Действия и выходы от представления дочернего контроллера до дочернего контроллера, который я установил на раскадровке, по-прежнему работают очень хорошо, даже если я никогда не вызываю addChildViewController
, и я не могу представить, на что еще это может повлиять.
Действительно, если я переписываю свой код, чтобы он не вызывал addChildViewController
, а вместо этого выглядел следующим образом...
- (void)showViewController:(UIViewController *)newViewController {
// Get the current child from a member variable of 'SideBarViewController'
UIViewController* oldViewController = currentChildViewController;
[oldViewController.view removeFromSuperview];
newViewController.view.frame = CGRectMake(
0, 0, self.view.frame.size.width, self.view.frame.size.height
);
[self.view addSubview: newViewController.view];
currentChildViewController = newViewController;
}
... тогда мое приложение все еще работает отлично, насколько я могу судить!
Документация Apple не проливает много света на то, что делает addChildViewController
, или почему мы должны это называть. Полный объем соответствующего описания того, что делает метод или почему его следует использовать в его разделе в UIViewController
класса UIViewController
, в настоящее время:
Добавляет данный контроллер представления как дочерний элемент.... Этот метод предназначен для вызова только реализацией пользовательского контроллера представления контейнера. Если вы переопределите этот метод, вы должны вызвать super в своей реализации.
Там также этот абзац ранее на той же странице:
Ваш контроллер представления контейнера должен связать дочерний контроллер представления с самим собой перед добавлением корневого представления потомков в иерархию представлений. Это позволяет iOS правильно направлять события на дочерние контроллеры представления и представления, которыми управляют эти контроллеры. Аналогично, после удаления дочернего корневого представления из иерархии представлений ему следует отключить этот дочерний контроллер представления от самого себя. Чтобы создать или разорвать эти ассоциации, ваш контейнер вызывает определенные методы, определенные базовым классом. Эти методы не предназначены для вызова клиентами вашего контейнерного класса; они должны использоваться только вашей реализацией контейнеров для обеспечения ожидаемого поведения сдерживания.
Вот основные методы, которые вам могут понадобиться вызвать:
addChildViewController:
removeFromParentViewController
willMoveToParentViewController:
didMoveToParentViewController:
но он не дает никакой подсказки относительно того, что представляют собой "события" или "ожидаемое поведение сдерживания", о которых идет речь, или почему (или даже когда) вызов этих методов является "существенным".
Все примеры пользовательских контроллеров представления контейнера в разделе "Настраиваемые контроллеры представления контейнера" в документации Apple, вызывают этот метод, поэтому я предполагаю, что он служит какой-то важной цели, помимо простого помещения дочернего ViewController в массив, но я не могу понять что это за цель. Что делает этот метод, и почему я должен называть его?