Отображение фиксированных и редактируемых элементов в списке источников - PullRequest
13 голосов
/ 28 ноября 2009

Фон

Я создаю список источников для своего приложения и хочу, чтобы он был структурирован аналогично iTunes с двумя типами элементов:

  • «Фиксированные» предметы - они не меняются и не могут быть перемещены - вверху
  • Редактируемые элементы внизу, которые могут быть изменены пользователем - перемещены, переименованы и т. Д. (В примере с iTunes, такие как Плейлисты и Умные Плейлисты)

В моей аналогии с iTunes:

iTunes Source List
(источник: perspx.com )

Пока я структурировал свои данные следующим образом:

  • Элементы, которые я хочу редактировать, являются «групповыми» элементами в виде Group Базовых сущностей данных.
  • Каждый элемент в списке источников представлен как SourceListItem обычный объект Objective-C, так что я могу связать каждый элемент с заголовком, значком, дочерними элементами и т. Д.
  • Фиксированные элементы в настоящее время представлены SourceListItem экземплярами, хранящимися в массиве в моем объекте контроллера.

Вопрос

Я не уверен, как объединить эти два типа элементов в Список источников, чтобы фиксированные элементы были вверху и всегда были там и не менялись, а редактируемые элементы были внизу и могли перемещаться и отредактировано.

Вот идеи, которые я выдвинул до сих пор:

  • Добавить фиксированные элементы в модель базовых данных. Это означает, что я могу создать сущность, представляющую элементы списка источников, и размещать мои фиксированные и редактируемые элементы в их экземплярах. Затем их можно привязать к столбцу таблицы Outline View с помощью контроллера Array / Tree. Однако это означает, что мне нужно будет создать новый объект для представления элементов списка источников, а затем синхронизировать Group с этим. Мне также нужно было бы каким-то образом создать все фиксированные элементы только один раз, и если что-то случится с любым из постоянных файлов хранилища, тогда фиксированные элементы не будут отображаться.

  • Объединение фиксированных элементов с элементами группы. Хотя оба хранятся в отдельных массивах, это можно сделать в контроллере для моего окна, когда представление Outline запрашивает данные (если принимается Протокол NSOutlineViewDataSource, а не привязки). Однако это означает, что мне нужно будет создать новые SourceListItem s для каждой группы в контроллере массива (чтобы связать каждую из них со значками и другими атрибутами), сохранить их, а затем наблюдать за контроллером группового массива на предмет изменений, чтобы удалить, добавить или изменить SourceListItem случаи, когда в группы вносятся изменения.

У кого-нибудь есть идеи, как мне это реализовать?

Мне бы хотелось, чтобы мое приложение было совместимо с OS X v10.5, поэтому я бы предпочел любые решения, которые не зависят от установленного Snow Leopard.

Ответы [ 2 ]

7 голосов
/ 28 ноября 2009

Я работаю над приложением, которое работает точно так же, и вот как я это делаю:

В моей базовой модели данных есть 5 основных объектов:

  1. AbstractItem - абстрактный объект, имеющий атрибуты, общие для всех элементов, например name, weight и editable. Также имеет два отношения: parent (отношение «один к одному» с AbstractItem) и children (отношение «ко многим» к AbstractItem и обратное значение parent).
  2. Group - конкретный дочерний субъект AbstractItem.
  3. Folder - конкретный дочерний субъект AbstractItem. Добавляет отношение «многие ко многим» к базовому объекту Item.
  4. SmartFolder - конкретный дочерний субъект Folder. Добавляет двоичный атрибут predicateData. Переопределяет метод доступа Folder "items", чтобы возвращать результаты выполнения запроса на выборку с предикатом, определенным атрибутом predicateData.
  5. DefaultFolder - конкретный дочерний субъект SmartFolder. Добавляет строковый атрибут identifier.

Для элементов раздела «Библиотека» я вставляю объекты DefaultFolder и присваиваю им уникальный идентификатор, чтобы можно было легко их извлекать и различать между ними. Я также даю им NSPredicate, что соответствует тому, что Items они должны показать. Например, «Music» DefaultFolder будет иметь предикат для извлечения всех элементов Music, «Podcasts» DefaultFolder будет иметь предикат для извлечения всех элементов Podcast и т. Д.

Элементы корневого уровня («Библиотека», «Общий ресурс», «Магазин», «Genius» и т. Д.) - это все Group элементы с nil родителем. Для групп и папок, которые нельзя редактировать, атрибут editable имеет значение NO.

Что касается фактического получения этого материала в вашем outlineView, вам придется самостоятельно реализовать протоколы NSOutlineViewDataSource и NSOutlineViewDelegate. Здесь слишком много поведенческой сложности, чтобы выкачивать ее через NSTreeController. Однако в моем приложении все поведение (даже перетаскивание) заняло менее 200 строк кода (так что это не , что плохо).

5 голосов
/ 28 ноября 2009

Не добавляйте глупости в свой набор данных просто для поддержки представления. Это не только идет вразрез с шаблоном проектирования MVC, но и добавляет ненужную сложность (то есть «больше возможностей для ошибок») к единственной самой важной части: управлению пользовательскими данными.

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

Вы, по сути, обменяли бы простоту настройки (и удобство уведомления об изменениях) на полный контроль над древовидной структурой.

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