Я просто вперше занурюю ноги в розробку iOS, і одне з перших, що мені довелося зробити, - це реалізувати користувальницький контролер перегляду контейнерів - давайте його назвати SideBarViewController
- який заміняє, який із кількох можливих контролерів подання даних на нього показує, майже точно як стандартний контролер Tab Bar . (Це майже контролер панелі вкладок, але із прихованим бічним меню замість панелі вкладок.)
Відповідно до інструкцій в документації 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
Довідковому класі , є:
Додає заданий контролер подання в якості дитини. ... Цей метод призначений лише для виклику реалізацією спеціального контролера перегляду контейнерів. Якщо ви перекриєте цей метод, ви повинні викликати супер у своїй реалізації.
На цій же сторінці є і цей параграф раніше:
Ваш контролер подання контейнерів повинен асоціювати контролер дочірнього виду з собою перед тим, як додати кореневий вигляд дитини до ієрархії перегляду. Це дозволяє iOS правильно маршрутизувати події до контролерів дитячого перегляду та представлень, якими керують контролери. Аналогічно, після видалення кореневого подання дитини з його ієрархії подання, він повинен відключити цей контролер дочірнього виду від себе. Щоб зробити або порушити ці асоціації, ваш контейнер викликає конкретні методи, визначені базовим класом. Ці методи не призначені для виклику клієнтами вашого контейнерного класу; вони повинні використовуватися лише реалізацією вашого контейнера, щоб забезпечити очікувану поведінку утримання.
Ось основні методи, які вам можуть знадобитися зателефонувати:
addChildViewController:
deleteFromParentViewController
willMoveToParentViewController:
didMoveToParentViewController:
але він не дає жодної підказки про те, про що говорять "події" або "очікувана поведінка стримування", або чому (або навіть коли) називати ці методи "суттєвим".
Приклади користувальницьких контролерів перегляду контейнерів у розділі «Користувальницькі контролери перегляду контейнерів» документації Apple називають цей метод, тому я припускаю, що він виконує якусь важливу мету, а не просто перескакувати дочірній ViewController на масив, але я не можу зрозуміти що таке ціль. Що робить цей метод, і чому я повинен його називати?