ソースリストでの固定および編集可能なアイテムの表示
-
06-07-2019 - |
質問
背景
アプリケーションのソースリストを作成していますが、iTunesの場合と同様の構造で、2種類のアイテムで構成する必要があります。
- "修正済み"アイテム–これらは変更されず、移動することはできません–上部
- ユーザーが変更できる 編集可能なアイテム。移動、名前の変更など(iTunesの例では、プレイリストやスマートプレイリストなど)
iTunesの例えで:
(ソース: perspx.com )
これまでにデータを構造化した方法は次のとおりです。
- 編集可能なアイテムは「グループ」です。
Group
Core Dataエンティティの形式のアイテム。 - ソースリストの各アイテムは、通常のObjective-Cオブジェクトとして
SourceListItem
として表されるため、各アイテムをタイトル、アイコン、子アイテムなどに関連付けることができます - 現在、固定アイテムは
SourceListItem
インスタンスで表され、コントローラーオブジェクトの配列に格納されています。
質問
これら2種類のアイテムをソースリストに統合する方法がわからないため、固定アイテムは常に最上部にあり、常に変更されず、編集可能なアイテムは最下部にあり、移動可能です。編集します。
これまでに思いついたアイデアは次のとおりです。
-
固定アイテムをコアデータモデルに追加します。これは、ソースリストアイテムを表すエンティティを作成し、これらのインスタンスに固定および編集可能なアイテムを配置できることを意味します。次に、これらをArray / Tree ControllerでOutline Viewテーブル列にバインドできます。ただし、これは、ソースリストのアイテムを表す新しいエンティティを作成し、
Group
をこれと同期する必要があることを意味します。また、すべての固定アイテムを一度だけ作成する方法が必要であり、永続ストアファイルのいずれかに何かが発生した場合、固定アイテムは表示されません。 -
固定アイテムとグループアイテムをマージします。両方とも別々の配列に保存されていますが、アウトラインビューがデータを要求するときにウィンドウのコントローラーで実行できます(採用する場合
NSOutlineViewDataSource
プロトコルであり、バインディングではありません)。ただし、これは、アレイコントローラの各グループに新しいSourceListItem
を作成し(それぞれをアイコンやその他の属性に関連付けるため)、これらを保存してから、グループアレイコントローラの変更を監視する必要があることを意味しますグループに変更が加えられたときに、SourceListItem
インスタンスを削除、追加、または変更します。
これを実装する方法について、もっと良いアイデアはありますか?
アプリケーションにOS X v10.5との互換性を持たせたいので、Snow Leopardのインストールに依存していないソリューションを希望します。
解決
これとまったく同じ動作をするアプリを開発していますが、次のようにします:
コアデータモデルには5つの主要なエンティティがあります:
-
AbstractItem
-name
、weight
、およびeditable などのすべてのアイテムに共通の属性を持つ抽象エンティティコード>。また、
parent
(AbstractItem
への1対1の関係)とchildren
(AbstractItem
、およびparent
の逆)。 -
Group
-AbstractItem
の具象子エンティティ。 -
Folder
-AbstractItem
の具体的な子エンティティ。基本的なItem
エンティティに多対多の関係を追加します。 -
SmartFolder
-Folder
の具象子エンティティ。バイナリ属性predicateData
を追加します。Folder
の" items"をオーバーライドします。predicateData
属性で定義された述語でフェッチ要求を実行した結果を返す関係アクセサー。 -
DefaultFolder
-SmartFolder
の具象子エンティティ。文字列属性identifier
を追加します。
"ライブラリ"セクション項目では、 DefaultFolder
オブジェクトを挿入し、それらに一意の識別子を与えて、簡単に取得して区別できるようにします。また、表示するはずの Items
に対応する NSPredicate
も提供します。たとえば、「音楽」 DefaultFolder
には、すべての音楽アイテムを取得するための述語があり、「ポッドキャスト」 DefaultFolder
には、すべてのPodcastアイテムなどを取得するための述語があります。
ルートレベルのアイテム(" Library"、" Shared"、" Store"、" Genius"など)はすべて、 nil を持つ
Group
アイテムです。コード>親。編集できないグループとフォルダーの editable
属性は NO
に設定されています。
outlineViewで実際にこれらのものを取得するには、 NSOutlineViewDataSource
および NSOutlineViewDelegate
プロトコルを自分で実装する必要があります。ここでは、 NSTreeController
を介してそれを引き出すにはあまりにも複雑な動作があります。しかし、私のアプリでは、200行未満のコードですべての動作を(ドラッグアンドドロップでさえ)取得しました(したがって、 that は悪くありません)。
他のヒント
ビューをサポートするためだけに、データセットにナンセンスを挿入しないでください。これはMVC設計パターンに反するだけでなく、ユーザーデータの管理という最も重要な部分に不必要な複雑さ(つまり、「バグの可能性が高い」)を追加します。
とはいえ、この特定のシナリオでバインディングを使用すると、大きな摩擦が発生します。バインディングを完全に回避しないのはなぜですか? NSOutlineViewDataSourceプロトコルを使用して、あなたは正しい軌道に乗っていると思いますが、あなたはそれを十分に取りませんでした。代わりに、このプロトコルに完全に依存します(まだ完全に有効であり、何らかの点で優れています)。
基本的に、ツリー構造を完全に制御するために、セットアップの容易さ(および変更通知の容易さ)と引き換えになります。