Просмотр вложенных контроллеров представления iOS внутри представления UIViewController?


91

Является ли обычно плохой практикой программирования в iOS иметь представление контроллера вложенного представления внутри представления UIViewController? Скажем, например, я хотел иметь какой-то интерактивный элемент, который реагировал бы на прикосновения пользователя, но занимал бы только 25% экрана.

Полагаю, я бы добавил этот контроллер вложенного представления в свой UIViewController, сказав что-то вроде:

[self.view addSubview: nestedViewController.view];

6
Вот полный учебник с множеством картинок !! stackoverflow.com/a/23403979/294884 Наслаждайтесь
Fattie

Ответы:


148

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

Реализация Контроллера представления контейнера

Это невероятно просто настроить с помощью Interface Builder с раскадровками, взгляните на представление контейнера в библиотеке объектов.

Вот надуманный пример в раскадровке. В этом примере у вас будет 4 контроллера представления, один из которых содержит 3 контейнера, и по одному для каждого контейнера. Когда вы представляете крайний левый контроллер, содержащий все контейнеры, Storyboard автоматически инициализирует и внедряет остальные 3. Вы можете получить доступ к этим дочерним контроллерам представления через childViewControllersсвойство или есть метод, который вы можете переопределить prepareForSegue:sender:и захватить контроллеры представления назначения переход, который будет называться. Это также хороший момент для передачи свойств дочерним контроллерам представления, если они необходимы.

введите описание изображения здесь


42
как «черт возьми» вы это делаете в раскадровке ?! это базовый вопрос .. Я не знаю ответа на него :) Вздох - отвечая на свой вопрос. Добавьте контейнер в сцену. Сформируйте его. Затем в пустых полях раскадровки создайте UIViewController. Затем щелкните правой кнопкой мыши и перетащите из этого контейнера (либо в списке навигатора, либо в графическом интерфейсе пользователя) в этот новый UIViewController. Во всплывающем окне выберите viewDidLoad-embed, чтобы начать. Спасибо, Крис! :)
Fattie

Ссылка, кстати, не работает.
Benjohn

2
@JoeBlow +1 "viewDidLoad-embed" Святая корова: кто бы мог подумать!
Drux

Спасибо, @ChrisWagner! Это критически важный фрагмент головоломки для реализации архитектуры MVVM и избегания Massive View Controller / "MVC";)
Роб

54

Я поместил этот код в родительский контроллер представления. У меня это отлично работает.

Obj C

-(void)viewDidLoad{
     [super viewDidLoad];
     InnerViewController *innerViewController = [self.storyboard instantiateViewControllerWithIdentifier:INNER_VIEW_CONTROLLER];
     [self addChildViewController:innerViewController];
     [self.view addSubview:innerViewController.view];
     [innerViewController didMoveToParentViewController:self];
}

Swift :

 let childViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ChildViewController"),
 self.addChildViewController(childViewController)
 self.view.addSubview(childViewController.view)
 childViewController.didMove(toParentViewController: self)

Другой вариант - использовать IB и поставить представление контейнера. UIViewController появится автоматически (в данном случае XCode 9): введите описание изображения здесь


2
Да! +1. Спасибо, что
включили

Я просто перетащил представление из контроллера дочернего представления в список родительского представления.
dimpiax

5

Вот мое решение Swift 3, основанное на ответе разработчиков Swift на FB

 let childViewController = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "ChildPageViewController"),
 self.addChildViewController(childViewController)
 self.view.addSubview(childViewController.view)
 childViewController.didMove(toParentViewController: self)
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.