Несколько контроллеров просмотра на экране одновременно? - PullRequest
20 голосов
/ 11 марта 2010

Я пытаюсь обернуть голову вокруг контроллеров в Cocoa Touch. Основная проблема заключается в том, что я хотел бы иметь более одного контроллера «на экране» одновременно - я хочу иметь большое представление (с контроллером A), состоящее из меньших представлений, управляемых их собственными контроллерами (скажем, B). Мне бы хотелось, чтобы это было так, потому что разделение делает код намного чище. Плохо то, что дополнительные контроллеры (типа B) не являются «первоклассными гражданами» на экране, например, они не получают запросы на авторотацию и уведомления. (И они не могут легко отображать модальные контроллеры, они должны отправить сообщение presentModal… на свой родительский контроллер.)

В чем отличие контроллеров A и B от точки зрения какао? Сохраняет ли система какой-либо указатель на «передний контроллер», привилегированный, на который она отправляет уведомления и тому подобное? Почему другие контроллеры не получают их, даже если их виды отображаются на экране? Считается ли хаком наличие нескольких контроллеров «на экране»? Или это поддерживается, и я просто упускаю какой-то пункт? Спасибо.


Подробнее о проблеме, которую я пытаюсь решить: я пишу простой браузер фотографий. Фотографии отображаются в полноэкранном режиме, пользователь может провести пальцем влево или вправо, чтобы изменить фотографии. Контроллер A заботится о прокручиваемой части, а контроллеры B сами заботятся о каждой фотографии.

Изоляция B казалась хорошей идеей, поскольку фотографии загружаются из сети, и многое может произойти, например, сеть может быть отключена и так далее. В контроллере B код довольно прост, поскольку B работает только с одной конкретной фотографией. Если бы я переместил код на контроллер A, все стало бы грязно.

Единственное, что мне не нравится в текущем решении, это то, что мне приходится обходить B вручную, а не быть «первоклассным» контроллером. Я должен передать некоторые вызовы вручную через A к B, и когда B хочет отобразить модальное диалоговое окно, он должен отправить presentModal… на A. Что ужасно.

Ответы [ 5 ]

14 голосов
/ 06 декабря 2011

Сейчас существует первоклассная поддержка этого сценария, начиная с iOS 5, она называется сдерживанием контроллера.

Контроллер Swift Controller

Контроллер objc .

12 голосов
/ 05 октября 2010

Это не тесно связано с первоначальным вопросом, но важно. Apple четко заявляет в Руководстве по программированию View Controller, что контроллер представления отвечает за управление только одним содержимым экрана:

"Каждый пользовательский объект контроллера представления, который вы создаете, отвечает за управление содержимым ровно на одном экране. Соотношение один к одному между контроллером представления и экраном является очень важным фактором при разработке вашего приложения. Вы должны не используйте несколько пользовательских контроллеров представления для управления различными частями одного и того же экрана. Точно так же не следует использовать один объект настраиваемого контроллера представления для управления стоимостью нескольких экранов.

Примечание. Если вы хотите разделить один экран на несколько областей и управлять каждой из них по отдельности, используйте общие объекты контроллера (пользовательские объекты, происходящие из NSObject) вместо объектов контроллера представления для управления каждым подразделом экрана. Затем используйте один объект контроллера представления для управления общими объектами контроллера. Контроллер представления координирует общее взаимодействие с экраном, но при необходимости пересылает сообщения в общие объекты контроллера, которыми он управляет. "

Однако в Руководстве по программированию iPad также говорится, что могут быть контроллеры представления контейнера:

"Контроллер представления отвечает за одно представление. В большинстве случаев представление контроллера представления должно заполнять весь промежуток окна приложения. Однако в некоторых случаях контроллер представления может быть встроен в другое представление контроллер (известный как контроллер представления контейнера) и представленный вместе с другим контентом. Контроллеры навигации и панели вкладок являются примерами контроллеров представления контейнера. "

Насколько мне известно, я бы не использовал контроллеры подвидов в контроллере представлений, но пытался создавать подклассы NSObject и отправлять им сообщения с моего основного контроллера представлений.

Также проверьте эту тему: Обсуждение MGSplitViewController

8 голосов
/ 11 марта 2010

Во-первых, и это важно, посмотрите контроллеры не отображаются "на экране" - просмотры делают. Ваш контроллер «верхнего уровня», безусловно, может передавать виды сообщений, которые вы описываете, своим «суб-представлениям-контроллерам». Фактически, так работает большинство приложений. Рассмотрим приложение с панелью вкладок, в которой представления используют контроллеры навигации. На самом деле у вас одновременно работают несколько контроллеров представления, каждый из которых имеет свое собственное представление на экране одновременно - ваш «корневой» контроллер представления будет экземпляром (или подклассом) UITabBarController, который затем имеет несколько вложенных UINavigationControllers, каждый который будет отображать вложенные контроллеры представления (например, экземпляр или подкласс UITableViewController).

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

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

6 голосов
/ 14 января 2016

Это довольно старый вопрос, но, так как я думаю, что есть люди, которые могут столкнуться с той же проблемой сегодня, я бы хотел поделиться своим решением. Я писал это приложение, которое имело этот единственный экран с большим количеством информации, нумерацией страниц, элементами управления и т. Д. Так как согласно документации MVC от Apple о роли ViewControllers, вы не должны реализовывать саму логику, или Получив доступ к модели данных непосредственно из нее, мне пришлось выбирать между наличием Massive ViewController с несколькими тысячами строк кода, которое было сложно поддерживать и отлаживать (даже с помощью модульных тестов), или найти новый способ.

Мое решение было использовать UIContainerView, как показано ниже: enter image description here

таким образом, вы можете реализовать логику каждой части в своем собственном ViewController, а родительский контроллер представлений заботится об ограничениях и размерах представлений.

Примечание. Этот ответ - всего лишь руководство, показывающее путь, вы можете найти хорошее и подробное объяснение того, как оно работает и как его реализовать ЗДЕСЬ

5 голосов
/ 28 февраля 2012

На самом деле вы можете заставить его работать раньше, чем iOS 5, так как большинство из нас ориентируется на 4.x и 5.x одновременно. Я создал решение, которое работает в обоих случаях, и оно прекрасно работает, его используют немногие приложения в магазине :) Прочитайте мою статью об этом или просто загрузите и используйте простой класс , который Я создал для этой цели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...