2015-07-27 6 views
2

Я реализую приложение, в котором строки из NSTableView можно перетаскивать и опускать в NSTokenField, но я изо всех сил пытаюсь реализовать drop-side взаимодействия. Я подклассифицировал NSTokenField (как показано ниже в коде отладки). Но я звоню только draggingEntered: и updateDraggingItemsForDrag:. Хотя я возвращаю действительный NSDragOperation (Copy), ни один из других методов в NSDraggingDestination не вызывается. Курсор кратковременно мигает к значку копирования при перемещении по полю токена, но затем возвращается к нормальному курсору.Удаление маркера в NSTokenField

Я попытался реализовать все методы, связанные с NSDraggingDestination для целей отладки, приведенные в коде ниже. Есть ли другой класс или часть NSTokenField, который обрабатывает капли? Можно ли переопределить это?

Я подтвердил, что у картона есть данные с допустимым типом картона.

let kPasteboardType = "SamplePasteboardType" 

class MyTokenField : NSTokenField 
{ 
    override func draggingEntered(sender: NSDraggingInfo) -> NSDragOperation { 
     // entered 
     NSLog("ENTERED") 

     // must come from same window 
     guard self.window == sender.draggingDestinationWindow() else { 
      return super.draggingEntered(sender) 
     } 


     // has valid pasteboard data? 
     let pb = sender.draggingPasteboard() 
     if let _ = pb.dataForType(kPasteboardType) { 
      NSLog("MATCHED") 
      return NSDragOperation.Copy 
     } 

     return super.draggingEntered(sender) 
    } 

    override func draggingUpdated(sender: NSDraggingInfo) -> NSDragOperation { 
     NSLog("UPDATED") 

     // must come from same window 
     guard self.window == sender.draggingDestinationWindow() else { 
      return super.draggingUpdated(sender) 
     } 

     // has valid pasteboard data? 
     let pb = sender.draggingPasteboard() 
     if let _ = pb.dataForType(kPasteboardType) { 
      return NSDragOperation.Copy 
     } 

     return super.draggingUpdated(sender) 
    } 

    override func draggingExited(sender: NSDraggingInfo?) { 
     NSLog("EXITED") 

     super.draggingExited(sender) 
    } 

    override func prepareForDragOperation(sender: NSDraggingInfo) -> Bool { 
     NSLog("PREPARE") 

     return super.prepareForDragOperation(sender) 
    } 

    override func performDragOperation(sender: NSDraggingInfo) -> Bool { 
     NSLog("PERFORM") 

     return super.performDragOperation(sender) 
    } 

    override func concludeDragOperation(sender: NSDraggingInfo?) { 
     NSLog("CONCLUDE") 

     super.concludeDragOperation(sender) 
    } 

    override func draggingEnded(sender: NSDraggingInfo?) { 
     NSLog("ENDED") 

     super.draggingEnded(sender) 
    } 

    override func updateDraggingItemsForDrag(sender: NSDraggingInfo?) { 
     // super.updateDraggingItemsForDrag(sender) 
     guard let drag = sender else { 
      return 
     } 

     let classes: [AnyClass] = [NSPasteboardItem.self] 
     let options: [String: AnyObject] = [NSPasteboardURLReadingContentsConformToTypesKey: [kPasteboardType]] 

     drag.enumerateDraggingItemsWithOptions(NSDraggingItemEnumerationOptions.ClearNonenumeratedImages, forView: self, classes: classes, searchOptions: options) { 
      (item, idx, stop) in 
      NSLog("\(item)") 
     } 
    } 
} 
+1

[Это делает звук, как все, что вам нужно, это два Гипсокартонные методы в 'NSTokenFieldDelegate'] (https://www.cocoanetics.com/2013/05/tokenize-this/). '', похоже, связано с манипулированием перемещением изображения, когда он входит в представление ... +1 тем не менее. Хороший вопрос. – stevesliva

ответ

1

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

  1. Подкласс класса NSTokenField не требуется.

  2. Мне нужно было реализовать функцию делегата tokenField(tokenField: NSTokenField, readFromPasteboard pboard: NSPasteboard) -> [AnyObject]? для поля токена.

  3. Мне пришлось изменить начало перетаскивания, чтобы сохранить строковое значение в картоне. Кажется, что если в картотеке нет строкового значения, то указанная выше функция делегата никогда не вызывается.