Я просто впервые погружаюсь в разработку для 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
Справочнике классов , в настоящее время:
Добавляет заданный контроллер представления как дочерний. ... Этот метод предназначен только для вызова реализацией настраиваемого контроллера представления контейнера. Если вы переопределите этот метод, вы должны вызвать super в своей реализации.
Также есть этот абзац ранее на той же странице:
Контроллер представления контейнера должен связать контроллер дочернего представления с собой перед добавлением корневого представления дочернего элемента в иерархию представлений. Это позволяет iOS правильно маршрутизировать события на контроллеры дочерних представлений и представления, которыми управляют эти контроллеры. Аналогично, после того, как он удаляет корневое представление дочернего элемента из его иерархии представлений, он должен отключить этот контроллер дочернего представления от самого себя. Чтобы создать или разрушить эти ассоциации, ваш контейнер вызывает определенные методы, определенные базовым классом. Эти методы не предназначены для вызова клиентами вашего контейнерного класса; они должны использоваться только реализацией вашего контейнера, чтобы обеспечить ожидаемое поведение сдерживания.
Вот основные методы, которые вам может понадобиться вызвать:
addChildViewController:
removeFromParentViewController
willMoveToParentViewController:
didMoveToParentViewController:
но он не дает никаких подсказок относительно того, какие «события» или «ожидаемое поведение сдерживания», о котором идет речь, или почему (или даже когда) вызов этих методов «необходим».
Все примеры настраиваемых контроллеров представления контейнеров в разделе «Настраиваемые контроллеры представления контейнеров» документации Apple вызывают этот метод, поэтому я предполагаю, что он служит какой-то важной цели, помимо простого добавления дочернего ViewController в массив, но я не могу понять что это за цель. Что делает этот метод и почему я должен его называть?