Почему Apple не разрешает создавать подклассы UINavigationController? И каковы мои альтернативы подклассам? - PullRequest
12 голосов
/ 21 декабря 2009

В настоящее время я создаю приложение iPhone с вкладками, в котором контроллер представления каждой вкладки является экземпляром UINavigationController, а каждый субконтроллер каждого из экземпляров UINavigationController является экземпляром UITableViewController. В идеале я хотел бы создать подкласс UINavigationController, чтобы контроллер для каждой вкладки являлся подклассом UINavigationController, который (очевидно, помимо всех стандартных функций UINavigationController) служит источником данных и делегатом для каждого из Табличные представления, связанные с его субконтроллерами. Попытка сделать это, похоже, нарушает базовую функциональность UINavigationController в подклассе.

Видя, как Apple говорит в своей документации для iPhone, что не следует создавать подклассы UINavigationController, и, кажется, что вещи ломаются, когда это происходит, мне интересно, как мне следует расширять функциональность UINavigationController's без создания подклассов, и вообще говоря, Как обходить ограничения на создание подклассов при разработке Какао.

Спасибо!

Ответы [ 6 ]

21 голосов
/ 21 декабря 2009

С какой стати вы хотите, чтобы UINavigationController служил источником данных для таблицы? Весь смысл UITableViewController состоит в том, что вы подклассируете его, и он действует как источник данных для UITableView, который он также помещает в родительское представление и заполняет его.

10 голосов
/ 04 августа 2013

Для справки, обратите внимание, что начиная с iOS 6, UINavigationController может быть разделен на подклассы юридически .

Этот класс обычно используется как есть, но может быть разделен на подклассы в iOS 6 и более поздних версиях. Справочник по классам UINavigationController

Конечно, это не значит, что вы всегда должны это делать. Но вы можете.

10 голосов
/ 21 декабря 2009

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

По сути, нет никаких причин, по которым вы не можете подкласса контроллера UINavigation добавить полностью ортогональный слой данных поверх него, потому что он не имеет ничего общего с пользовательским интерфейсом или поведением, которым управляет UINavigationController (это то, чем Apple обеспокоена, с которой вы будете возиться ). Для тех, кто против этой идеи, думайте о ней как о хранилище данных для каждой вкладки, к которому все страницы на вкладке могут обращаться, а не к каждой странице в системе, для которой нужно перейти в AppDelegate или иметь кучу синглетонов. Ну, в основном это одиночный, но, по крайней мере, тот, который уже существует и автоматически передает ссылку.

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

1 голос
/ 21 декабря 2009

Если доступная иерархия контроллера не удовлетворяет вашим потребностям с точки зрения обработки данных (я предполагаю, поскольку мы не знаем, почему вы хотите, чтобы один объект был источником данных для нескольких представлений), вы всегда можете создать дополнительные данные и /или классы контроллера (подклассы NSObject по крайней мере).

Вы можете сохранять данные или другие объекты при различных видах изменения вида.(1) свойство вашего класса делегата приложения.Любой объект в вашем приложении может получить ваш экземпляр делегата приложения с

[[UIApplication sharedApplication] delegate]

Используйте это экономно, так как он по сути создает глобальные переменные.

(2) Вы можете передавать данные или другие объекты с контроллера на контроллеркогда вы толкаете подклассы контроллера представления или выводите их на вкладки.

(3) Базовые данные - это еще один способ, но вам нужно много какао за пояс, и вам все равно придется управлять экземплярами контекста.

1 голос
/ 21 декабря 2009

Насколько я понимаю, подклассы не поощряются, потому что Цель C предоставляет подклассу слишком большой доступ к внутренним работам его суперкласса.

Предлагаемая альтернатива написанию подкласса - написать делегат, в данном случае UINavigationControllerDelegate. Затем вы можете инкапсулировать конкретное поведение, которое вы хотите расширить, в этот класс делегатов и связывать его с UINavigationController всякий раз, когда вам это нужно.

0 голосов
/ 21 декабря 2009

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

...