Mostrar elementos fijos y editables en una lista de origen
-
06-07-2019 - |
Pregunta
Fondo
Estoy creando una Lista de fuentes para mi aplicación y quiero que esté estructurada de manera similar a la de iTunes, con dos tipos de elementos:
- " fijo " artículos & # 8211; estos no cambian y no se pueden mover alrededor & # 8211; en la parte superior
- Elementos editables debajo, que pueden ser modificados por el usuario & # 8211; movido, renombrado, etc. (en el ejemplo de iTunes, como listas de reproducción y listas de reproducción inteligentes)
En mi analogía de iTunes:
(fuente: perspx.com )
La forma en que he estructurado mis datos hasta ahora es la siguiente:
- Los elementos que quiero que sean editables son "grupo" elementos, en forma de entidades de
Group
Core Data. - Cada elemento de la Lista de fuentes se representa como un objeto regular de
SourceListItem
Objective-C para que pueda asociar cada elemento con un título, icono, elementos secundarios, etc. - Los elementos fijos están representados actualmente por instancias
SourceListItem
, almacenadas en una matriz en mi objeto controlador.
La pregunta
No estoy seguro de cómo fusionar estos dos tipos de elementos en la Lista de fuentes, de modo que los elementos fijos estén en la parte superior y siempre allí y no cambien, y los elementos editables estén en la parte inferior y se puedan mover. y editado.
Estas son las ideas que se me han ocurrido hasta ahora:
Agregar los elementos fijos al modelo de Datos básicos. Esto significa que puedo crear una entidad para representar los elementos de la Lista de origen y colocar mis elementos fijos y editables en instancias de estos. Luego, estos pueden vincularse a la columna de la tabla Vista de esquema con un Controlador de matriz / árbol. Sin embargo, esto significa que tendría que crear una nueva entidad para representar los elementos de la Lista de fuentes y luego sincronizar los
Group
s con esto. También tendría que tener alguna forma de crear todos los elementos fijos solo una vez, y si algo le sucediera a cualquiera de los archivos de almacenamiento persistentes, los elementos fijos no se mostrarían.Fusionar los elementos fijos con los elementos del grupo. Si bien ambos están almacenados en matrices separadas, esto podría hacerse en el controlador de mi ventana cuando la Vista de esquema solicita los datos (si adopta el protocolo
NSOutlineViewDataSource
, no los enlaces). Sin embargo, esto significa que tendría que crear nuevosSourceListItem
s para cada grupo en el controlador de matriz (para asociar cada uno con los iconos y otros atributos), almacenarlos y luego observar los cambios en el controlador de matriz de grupo eliminar, agregar o modificar las instanciasSourceListItem
cuando se realizan cambios en los grupos.
¿Alguien tiene mejores ideas sobre cómo puedo implementar esto?
Me gustaría que mi aplicación fuera compatible con OS X v10.5, por lo que preferiría cualquier solución que no dependiera de tener Snow Leopard instalado.
Solución
Estoy trabajando en una aplicación que tiene exactamente el mismo comportamiento, y así es como lo estoy haciendo:
Tengo 5 entidades principales en mi modelo de datos principales:
-
AbstractItem
: una entidad abstracta que tiene los atributos comunes a todos los elementos, comoname
,weight
yeditable . También tiene dos relaciones:
parent
(relación uno aAbstractItem
) ychildren
(relación muchos aAbstractItem
y el inverso deparent
). -
Group
- Entidad secundaria concreta deAbstractItem
. -
Carpeta
- Entidad secundaria concreta deAbstractItem
. Agrega una relación de muchos a muchos a la entidad básicaItem
. -
SmartFolder
- Entidad secundaria concreta deCarpeta
. Agrega un atributo binariopredicateData
. Invalida los '' elementos '' deFolder
relación de acceso para devolver los resultados de ejecutar una solicitud de captación con el predicado definido por el atributopredicateData
. -
DefaultFolder
: entidad secundaria concreta deSmartFolder
. Agrega un atributo de cadenaidentificador
.
Para la " Biblioteca " En los elementos de la sección, inserto objetos DefaultFolder
y les doy un identificador único para que pueda recuperarlos fácilmente y diferenciarlos. También les doy un NSPredicate
que corresponde a los Elementos
que deben mostrar. Por ejemplo, la "Música" DefaultFolder
tendría un predicado para recuperar todos los elementos de Música, los " Podcasts " DefaultFolder
tendría un predicado para recuperar todos los elementos de Podcast, etc.
Los elementos de nivel raíz ("Biblioteca", "Compartido", "Tienda", "Genio", etc.) son todos elementos Group
con un nil padre. Los grupos y carpetas que no se pueden editar tienen su atributo
editable
establecido en NO
.
En cuanto a obtener realmente estas cosas en su outlineView, deberá implementar los protocolos NSOutlineViewDataSource
y NSOutlineViewDelegate
usted mismo. Hay demasiada complejidad de comportamiento aquí para bombearlo a través de un NSTreeController
. Sin embargo, en mi aplicación, obtuve todo el comportamiento (incluso arrastrar y soltar) en menos de 200 líneas de código (por lo que no es eso malo).
Otros consejos
No inyecte tonterías en su conjunto de datos simplemente para admitir una vista. Esto no solo va en contra del patrón de diseño MVC, sino que agrega una complejidad innecesaria (es decir, "más potencial para errores") a la parte más importante: la gestión de los datos del usuario.
Dicho esto, el uso de enlaces con este escenario particular es lo que está causando tanta fricción. ¿Por qué no evitar las fijaciones por completo? Creo que está en el camino correcto, utilizando el protocolo NSOutlineViewDataSource, pero no lo llevó lo suficientemente lejos. En cambio, confíe plenamente en este protocolo (que sigue siendo perfectamente válido y de alguna manera superior).
En esencia, cambiaría la facilidad de configuración (y la notificación de cambio fácil) por un control total sobre la estructura de árbol.