2011-12-31 11 views
6

新しいLion機能を使用してアプリケーションの行を並べ替えるのに問題があります。私はoutlineView:pasteboardWriterForItem:を使用して行インデックスを格納していますので、後でドロップを検証/受け入れるときにアクセスできます。私は新しいNSPasteboardItemを返すために作成し、ように行番号を保存しようとしています:Lionでドラッグしてテーブル行を並べ替える

[pbItem setData: [NSKeyedArchiver archivedDataWithRootObject: [NSNumber numberWithInteger: [fTableView rowForItem: item]]] 
                forType: TABLE_VIEW_DATA_TYPE]; 

TABLE_VIEW_DATA_TYPEは、私はドラッグ厚紙で私のカスタムデータを区別するために使用しているカスタム文字列です。私はこれらの行をドラッグする以外では使用しません。

ドラッグをしようとすると、私はコンソールで受け取る:もちろん'TableViewDataType' is not a valid UTI string. Cannot set data for an invalid UTI.

Iは、内蔵のUTIペーストボードのためのいくつかを使用することができ、それらのどれも適用されません(と彼らがドラッグを受け入れるようになり使用すると、他のドラッグ行ではないはずです)。ドラッグするだけでカスタムUTIを定義する方法のように、私が紛失しているものがありますか(内部のドラッグの外側には使用しないので「実際の」UTIにしないで公開するべきではありません)。

ありがとうございました!

答えて

2

NSPasteboardItemというバニラを使用する代わりに、NSPasteboardWritingプロトコルに準拠したカスタムオブジェクトを作成する必要があります。

カスタムオブジェクトでは、writableTypesForPasteboard:を実装して、ペーストボードアイテムがサポートするカスタムUTIのリストを返すことができます。次に、pasteboardPropertyListForType:を実装して、ペーストボードが要求したときに適切なカスタムUTIのオブジェクトのplist表現を返します。

+propertyListWithData:options:format:error:メソッドNSPropertyListSerializationを使用して、任意のデータからplistを作成できます。

テーブルビューのデータソースでtableView:pasteboardWriterForRow:をオーバーライドすると、カスタムオブジェクトのインスタンスが返されます。

+1

ありがとう、私は応答を感謝します。私はまだ、行が再配置されるのを追跡するのはとても複雑だと本当に驚いています。 – livings124

+0

'writableTypesForPasteboard:'に対して私のカスタムUTIを返す 'NSPasteboardWriting'に適合するオブジェクトを実装しましたが、_'TableViewDataType 'は有効なUTI文字列ではありません。無効なUTIを-writeableTypesForPasteboardから返された型として使用することはできません:class TableViewDragNode._ – livings124

+0

の場合Info.plistでのドラッグ操作のカスタムUTIを宣言する以外に、オプションはありません。私は同意する、これは奇妙な制限であるようだ。私は実行時にUTIを定義することはできないと考えています。Info.plistでハードコードされている必要があります。 –

5

ドラッグするオブジェクトのインデックスを側面のインスタンス変数に保存することもできます。ペーストボードにすべてを置くことは、別のアプリからアイテムを受け入れるか、またはその逆でなければ、厳密には必要ありません。

  1. awakeFromNibでは、NSStringPboardTypeに登録します。
  2. In ... pasteboardWriterForRow、[NSString string]を返します。
  3. ... draggingSession:willBegin ...、インスタンス変数をトラッキングするインデックスに設定します。
  4. validateDropでは、インスタンス変数がnilであるかビューが自分のものでない場合はNSDragOperationNoneを返します。
  5. ... draggingSession:ended ...、インスタンス変数を指定しないでください。

私はテーブルビューのテクニックを使用していますが、アウトラインビューとほぼ同じでなければなりません。

6

私は、選択したオブジェクトを新しい場所にドラッグすることで再配置したいオブジェクトのグリッドを持っていたこと以外は同様の要件がありました。これを行うには、カスタムオブジェクトを作成し、とNSPasteboardReadingのプロトコル(NSPasteboardReadingAsKeyedArchiveというデータを読み取る場合はNSCodingプロトコル)を実装するなど、いくつかの方法がありますが、これは内部に残っているオブジェクトのドラッグ応用。

NSPasteboardItemをカスタムUTIタイプのラッパーとして使用しています(すでにNSPasteboardWritingNSPasteboardReadingプロトコルを実装しています)。 「XXXが有効なUTI文字列ではありません:これは、そうでない場合は、フォームのエラーが発生します「com.domain.MyApp」形式で定義する必要が

#define kUTIMyCustomType @“com.mycompany.MyApp.MyCustomType”

:最初のカスタムUTIタイプを宣言します。無効なUTIのデータを設定することはできません」Appleはこれをドキュメントに記述しています。

次に、このカスタムUTIタイプを、ドラッグが発生するビューに登録する必要があります。これは実行時に行うことができ、.plistの追加は必要ありません。あなたのビューのinitメソッドでは、以下を追加します。

[self registerForDraggedTypes:[NSArray arrayWithObjects:(NSString *)kUTIMyCustomType, nil]]; 

、デリゲートは、このビューの設定、およびデリゲートオブジェクトが必要NSDraggingSourceNSDraggingDestinationプロトコルのメソッドを実装していることを確認してください。これにより、指定されたコントローラオブジェクトが、モデルデータ(つまりインデックス)をクエリすることを含む可能性のあるペーストボード上のデータの配置を処理できるようにすることで、MVCデザインパターンの破損を回避できます。ドラッグするときに具体的には、オブジェクトのインデックスをペーストボードドラッグに配置するために移動する

は、あなたのインデックスデータのNSPasteboardItemラッパーとして開始されます:

- (void) draggingSession:(NSDraggingSession *)session willBeginAtPoint:(NSPoint)screenPoint 
{ 
    NSPasteboard * pboard = [NSPasteboard pasteboardWithName:NSDragPboard]; 
    [pboard clearContents]; 

    NSMutableArray * selectedIndexes = [NSMutableArray array]; 

    // Add NSString indexes for dragged items to pasteboard in NSPasteboardItem wrappers. 
    for (MyModel * myModel in [self selectedObjects]) 
    { 
     NSPasteboardItem * pasteboardItem = [[[NSPasteboardItem alloc] init] autorelease]; 
     [pasteboardItem setString:[NSString stringWithFormat:@"%@", [myModel index]] 
         forType:kUTIMyCustomType]; 
     [selectedIndexes addObject:pasteboardItem]; 
    } 

    [pboard writeObjects:selectedIndexes]; 
} 

そして、ドラッグ操作が完了すると、ドラッグしたインデックスを読むことNSPasteboardItemデータ:

関連する問題