Что происходит под капотом, когда мы представляемViewController? - программирование
Подтвердить что ты не робот

Что происходит под капотом, когда мы представляемViewController?

Учитывая приведенный ниже код

self.view.backgroundColor = [UIColor yellowColor];
MyViewController *myVC = [[MyViewController alloc] initWithNibName:@"MyView" bundle:nil]
myVC.view.backgroundColor = [UIColor clearColor];
myVC.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:myVC animated:NO completion:nil];

Что происходит под капотом, когда мы вызываем presentViewController? Когда myVC виден, я не вижу желтый цвет, тогда я проверил myVC.view.superView в методе viewDidAppear, и это UIWindow.

Q1. Является ли это до тех пор, пока модальное окно не появится? Представленный viewController.view(self.view в приведенном выше случае) удаляется из иерархии View и представленViewController.view(myVC.view в приведенном выше случае) добавляется через UIWindow?

Q2. Что будет, если myVC.modalPresentationStyle!= UIModalPresentationFullScreen?

Q3. Является ли iOS также удалять все представления из UIWindow, кроме представленногоViewController.view, до тех пор, пока полнофункциональный модальный диалог не будет оптимизирован? Если НЕТ, почему бы и нет?

4b9b3361

Ответ 1

Сначала обсудим случай без анимации.

Перед вызовом present:

  • В вашем окне есть одна иерархия представлений, начиная с ее представления rootViewController.

После вызова present:

  • Иерархия представлений сохраняется без изменений.
  • В окно добавляется специальный полноэкранный вид под названием "dimming view" (то есть не внутри представления rootViewController, а внутри окна (это также окно UIView). Это представление прозрачно, затемняет подающий элемент управления и блокирует взаимодействие пользователя.
  • Представленный (модальный) вид контроллера затем добавляется также в окно.

Между окном и представленным окном контроллера добавляются некоторые другие представления. Если вы зарегистрируете свою иерархию представлений, вы увидите классы с именем _ControllerWrapperView или что-то подобное. Однако это изменилось между версиями iOS, и вы не должны полагаться на структуру представления. Обратите внимание, что модальный контроллер никогда не может быть прозрачным, поскольку он не является прямым подсмотром окна, а обертки между контроллером и окном не прозрачны.

Анимированный случай почти такой же. Только между этими шагами есть несколько фантазийных анимаций.

Изменить 2: Ответ был немного неправильным. Существует большая разница между представленными контроллерами iPhone и iPad.

На iPhone представленные контроллеры всегда отображаются в полноэкранном режиме, и отображающие контроллеры фактически удаляются из окна.

На iPad, если представленный контроллер не является полноэкранным (см. UIModalPresentationStyle), отображающий контроллер остается в окне.

Ваши вопросы:

Означает ли это, пока модальное окно не появится? Представленный viewController.view(self.view в приведенном выше случае) удаляется из иерархии View, а представленное представлениеViewController.view(myVC.view в приведенном выше случае) добавляется через UIWindow?

Если контроллер находится в полноэкранном режиме, это утверждение верно. В противном случае контроллер представления представления остается там, но все содержимое перекрывается другими представлениями (даже если они полупрозрачны). Кроме того, между представленным и представлением контроллеров всегда есть некоторые представления.

Что будет, если myVC.modalPresentationStyle!= UIModalPresentationFullScreen?

См. ответ на предыдущий вопрос - на iPhone, не будет никакой разницы.

Является ли iOS также удалять все представления из UIWindow, кроме представленногоViewController.view, до тех пор, пока полномасштабный модальный диалог не будет оптимизирован? Если НЕТ, почему бы и нет?

Из моих тестов из иерархии окон удаляется только презентационный контроллер. Это, вероятно, для оптимизации производительности чертежа. Это единственный контроллер, который система может безопасно удалить. Удаление любого другого вида может вызвать проблемы (например, представления, которые должны быть всегда видны).

Edit: Если вы хотите создать прозрачный контроллер, вы можете:

  • Добавить представление непосредственно в иерархию вашего представления (либо в виде контроллера, либо в окно) с анимацией перехода (+[UIView transition...])
  • То же самое, но также добавление дочернего контроллера к вашему контроллеру.