2011-12-31 3 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.

내가의 일부를 사용할 수있는 pasteboards에 대한 요로 감염 내장,하지만 그들 중 누구도이 적용되지 않습니다 (그들에게 사용하는 것은 받아 들일 드래그가 다른 드래그 원인 행보다 낫다.) 제가 끌고있는 커스텀 UTI를 정의하는 방법처럼, 실종 된 것입니까? (내부 드래그를 벗어나는 용도가 없으므로 "실제"UTI로 만들지 않고 public이되어서는 안됩니다).

도움 주셔서 감사합니다.

답변

2

NSPasteboardItem 바닐라를 사용하는 대신 NSPasteboardWriting 프로토콜을 준수하는 사용자 지정 개체를 만들어야합니다.

사용자 지정 개체에서 writableTypesForPasteboard:을 구현하여 대지 항목에서 지원하는 사용자 지정 UTI 목록을 반환 할 수 있습니다. 그런 다음 pasteboardPropertyListForType:을 구현하여 마분지가 요청할 때 적절한 사용자 정의 UTI에 대한 객체의 plist 표현을 반환합니다.

+propertyListWithData:options:format:error: 방법을 사용하여 임의의 데이터에서 plast를 만들 수 있습니다. NSPropertyListSerialization입니다.

그러면 사용자 정의 개체의 인스턴스를 반환하기 위해 테이블보기 데이터 원본에서 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. ... pasteboardWriterForRow에서 [NSString string]을 반환합니다.
  3. ... draggingSession : willBegin ..., 추적 할 색인으로 인스턴스 변수를 설정하십시오.
  4. validateDrop에서 인스턴스 변수가 nil이거나 뷰가 사용자가 아닌 경우 NSDragOperationNone을 반환합니다.
  5. 있음 ... draggingSession : ended ..., 인스턴스 변수가 없습니다.

호프가 도움이 되었으면 ... 표보기에이 기술을 사용하고 있지만 아웃 라인보기와 거의 동일해야합니다.

6

필자는 선택된 개체를 새 위치로 끌어서 배열하려는 개체 그리드가있는 것을 제외하고는 비슷한 요구 사항이있었습니다.이렇게하려면 사용자 정의 객체를 만들고 및 NSPasteboardReading 프로토콜을 구현하고 (데이터를 NSPasteboardReadingAsKeyedArchive으로 읽으려는 경우 NSCoding 프로토콜을 구현하는 등) 여러 가지 방법이 있지만이 방법은 내부에 남아있는 객체를 드래그하여 과도한 것으로 보입니다. 신청.

나는 사용자 정의 UTI 유형 (이미 NSPasteboardWritingNSPasteboardReading 프로토콜을 구현 함)이있는 래퍼로 NSPasteboardItem을 사용했습니다.

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

이 그렇지 않으면 양식의 오류를 얻을 것이다 'com.domain.MyApp'형식으로 정의 할 필요가있다 : "XXX는 유효한 UTI의 문자열이 아닌 첫 번째 사용자 정의 UTI 유형을 선언합니다. 유효하지 않은 UTI에 대해 데이터를 설정할 수 없습니다. "Apple은 자신의 문서에서이를 언급합니다.

그런 다음이 사용자 지정 UTI 유형을 드래그가 발생하는보기에 등록해야합니다. 이는 런타임에 수행 할 수 있으며 .plist 추가가 필요하지 않습니다.

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

지금, 대리인이보기에 대해 설정되어 있는지 확인하고 위임 개체가 필요한 NSDraggingSourceNSDraggingDestination 프로토콜 메소드를 구현 :보기의 init 메소드에서 다음과 같은 추가합니다. 이렇게하면 지정된 컨트롤러 객체가 모델 데이터 (즉, 인덱스)를 쿼리하는 데 필요한 데이터를 대지에 배치하는 것을 처리 할 수 ​​있으므로 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 데이터 :

- (BOOL) performDragOperation:(id <NSDraggingInfo>)sender 
{ 
    NSPasteboard * pasteboard = [sender draggingPasteboard]; 

    // Check for custom NSPasteboardItem's which wrap our custom object indexes. 
    NSArray * classArray = [NSArray arrayWithObject:[NSPasteboardItem class]]; 
    NSArray * items = [pasteboard readObjectsForClasses:classArray options:[NSDictionary dictionary]]; 

    if (items == nil) 
     return NO; 

    // Convert array of NSPasteboardItem's with NSString index reps. to array of NSNumber indexes. 
    NSMutableArray * indexes = [NSMutableArray array]; 
    for (NSPasteboardItem * item in items) 
     [indexes addObject:[NSNumber numberWithInteger:[[item stringForType:kUTIMyCustomType] integerValue]]]; 

    // 
    // Handle dragged indexes… 
    // 

    return YES; 
}