2013-07-31 2 views
2

У меня есть два экрана NSTableViews на экране; Я просто хочу перетащить строку из одной таблицы в другую таблицу. Я вижу много советов здесь и там, но я не вижу полного примера, и я немного смущен. Я видел examples, которые были совершенно разными для примеров приложений для яблок TableView playground и drag and drop outlineView.Как реализовать перетаскивание с NSOutlineVIew

Я решил использовать метод Яблок, но теперь я застрял. Настольная площадка TableView реализует эти методы в своем модельном объекте.

- (NSArray *)writableTypesForPasteboard:(NSPasteboard *)pasteboard 
- (id)pasteboardPropertyListForType:(NSString *)type 
- (NSPasteboardWritingOptions)writingOptionsForType:(NSString *)type pasteboard:(NSPasteboard *)pasteboard 

Я не понимаю, как их установить. Для 1-го метода я вернул массив со строкой @"com.mycompany.myapp.mypasteboardtype", как предложено в this вопрос.

Что я должен поставить для второго метода? Моя модель - это настраиваемый объект с несколькими строками, массивами и переменными словаря. Я также не понимаю третий метод. Хотелось бы, чтобы появился какой-то пример, который я видел, что делает простое перетаскивание из одной таблицы в другую с помощью настраиваемого объекта модели.

EDIT: Моя реализация на основе ответа ниже

-(id)pasteboardPropertyListForType:(NSString *)type { 
    return [NSKeyedArchiver archivedDataWithRootObject:self]; 
} 

-(NSArray *)writableTypesForPasteboard:(NSPasteboard *)pasteboard { 
    return [NSArray arrayWithObject:myDragType]; 
} 
// Other methods that need to be implemented 

-(id)initWithPasteboardPropertyList:(id)propertyList ofType:(NSString *)type { 
    return [NSKeyedUnarchiver unarchiveObjectWithData:propertyList]; 
} 

+(NSArray *)readableTypesForPasteboard:(NSPasteboard *)pasteboard { 
    return [NSArray arrayWithObject:myDragType]; 
} 

// And finally your object needs comply with NSCoder protocol. These following 2 methods needs to go in the object model associated with a row. 
-(void)encodeWithCoder:(NSCoder *)aCoder { 
    [aCoder encodeObject:oneOfMyIvarsToEncode forKey:@"someKey"]; 
} 

-(id)initWithCoder:(NSCoder *)aDecoder { 
    self = [super init]; 
    if (self) { 
     oneOfMyEndodedIvars = [aDecoder decodeObjectForKey:@"someKey"]; 
    } 

    return self; 
} 

ответ

2

Что я должен поставить для [pasteboardPropertyListForType:]? Моя модель - это настраиваемый объект с несколькими строками, массивами и переменными словаря.

Это зависит от того, на каком типе вас просят.

Если это ваш собственный пользовательский тип, который вы создали, вы можете положить все, что захотите. В самом деле, если это ваш тип, который вы изобрели, вы можете вернуть все, что захотите, если это действительный список свойств. Вам просто нужно убедиться, что ваш код пасты/перетаскивания (картон , читающий) ожидает того же материала.

Если вы хотите поддержать внутренние затяжки (изменение порядка и/или перемещение в иерархии), вы должны иметь по крайней мере один пользовательский тип, который идентифицирует объекта, так что вы можете смотреть один и тот же объект, принимая падение (чтобы переместить его, а не дублировать). Для объекта Core Data вы можете использовать абсолютную строку the object's identifying URI.

Если вы хотите поддерживать перетаскивание в другие приложения, у вас должен быть хотя бы один нестандартный тип, который распознают другие приложения. Тип, который вы поддерживаете, будет зависеть от того, что представляет ваша модель: если это изображения (или рецепты для их создания, например, стеки слоев), вы можете поддерживать PNG, TIFF, JPEG и т. Д .; если они являются контактами, вы можете поддерживать vCard; если они являются текстом, вы можете поддерживать простой текст и/или RTF и/или HTML и/или WebArchive и/или Microsoft Word; и т. д.

Вы возвращаете массив типов, с помощью которых этот объект может быть превращен из writableTypesForPasteboard:; после этого pasteboardPropertyListForType: должен посмотреть, для какого типа он был запрошен, и вернуть список свойств этого типа.

Для большинства внешних форматов pasteboardPropertyListForType: должен возвращать объект данных. Для ваших собственных пользовательских форматов это обычно либо словарь, либо набор словарей, хотя, как я уже сказал, единственными реальными требованиями являются то, что он должен быть каким-то плюсом, и ваш код чтения должен быть в состоянии его понять.

Я также не понимаю [writingOptionsForType:pasteboard:].

Вы должны вернуть битную маску, указывающую, когда и как вы будете писать тип в картон. The available options are documented.

В настоящее время существует только одно: вы можете обещать данные. Это означает, что картон не будет сразу запрашивать данные; он будет ждать, пока пользователь не встанет или не упадет где-нибудь (или данные в противном случае запрошены любым приложением, например, плохо написанный метод проверки кавычек может запрашивать данные и проверять их во время проверки, а не отменять прием). Только тогда он вызовет pasteboardPropertyListForType: для этого типа. (И это вариант для каждого типа, вы можете обещать некоторые типы, но не другие).

Обещание отлично подходит для данных, которые дорого вычислять и/или хранить; например, сжатый архив (вычислить) или большое изображение (хранилище).

+0

Хорошо. один окончательный вопрос о том, что касается 'pasteboardPropertyListForType:', вы сказали, что я могу возвращать любой тип, пока его список свойств. В примерах TableViewPlaygorund они вернули 'self'. Если я попытаюсь вернуть любой другой объект, отличный от self, я получаю предупреждение @ «Несовместимые типы указателей ..», это может вызвать проблемы? –

+0

@Jai: Какой класс в этом образце вы смотрите? –

+0

Ничего. Кажется, я решил это. Я буду отмечать этот ответ так же корректно, как я получил информацию этого ответа плюс от другого вопроса, на который вы ответили, прежде чем ----> http://stackoverflow.com/questions/7243668/nspasteboard-and-simple-custom-data –