2011-01-08 31 views
5

直到今天,我從來沒有機會使用NSWindow本身以外的其他任何東西作爲NSDraggingDestination。當使用一個窗口作爲一個通用的拖動目標時,NSWindow會將這些消息傳遞給它的委託,讓您可以處理drop而不需要繼承NSWindow。Cocoa NSTextField拖放需要子類...真的嗎?

docs說:

雖然NSDraggingDestination被聲明爲非正式協議 ,你 創建採用協議 NSWindow和一個NSView子類只需要 實現那些 相關方法。 (NSWindow和NSView 類爲所有的 方法提供了私有的 實現。)其窗口對象或其代表可以實現這些方法的窗口對象或 ;然而,如果 在 位置都有實現,則代表的 實施優先。

今天,我有一個窗口,上面有兩個NSTextFields,我想他們有不同的丟棄行爲,我不希望讓滴其他地方的窗口。我解釋文檔的方式似乎是要麼繼承NSTextField,要麼在窗口的委託上創建一些巨大的意大利麪條件拖放處理程序,以便按照每個視圖檢查draggingLocation,以選擇不同的拖放區域行爲每個領域。

集中的NSWindow-基於委託的放置處理程序方法好像在任何情況下都會有很多繁瑣的放置目標視圖。同樣,無論情況如何,子類化方法似乎都很麻煩,因爲現在放置處理代碼存在於視圖類中,所以一旦您接受了放置,您就必須想出一些方法將丟棄的數據整理回模型。 bindings docs通過以編程方式設置UI值來警告您嘗試驅動綁定。所以現在你仍然陷入困境。

所以我的問題是:「真的!?這些是唯一可用的選擇嗎?還是我錯過了一些簡單的東西?

謝謝。

+0

您應該修正問題標題中的錯字(NSTextView!= NSTextField)。 – NSGod 2011-01-08 22:45:22

回答

6

經過多一點研究後,它顯示出「是的,實際上,您的兩個選擇是要麼NSTextField的子類,要麼使用您的NSWindowDelegate來處理丟棄。」我會更進一步,並聲稱兩種更好的方式,對於花園種類的情況,「我想在一個窗口中放置多個拖放區域」是使用命中檢查的NSWindowDelegate方法,因爲您可以避免在視圖方面有你的拖放處理代碼。我結束了這個draggingUpdated:方法在我的窗前,委託類:

- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender 
{ 
    NSPasteboard *pboard = [sender draggingPasteboard]; 
    NSDragOperation sourceDragMask = [sender draggingSourceOperationMask]; 

    if ([pboard.types containsObject: NSFilenamesPboardType] && (sourceDragMask & NSDragOperationCopy)) 
    { 
     NSView* hitView = [sender.draggingDestinationWindow.contentView hitTest: sender.draggingLocation]; 
     if (hitView && (hitView == mSourceTextField || hitView == mDestTextField)) 
     { 
      return NSDragOperationCopy;    
     } 
    } 

    return NSDragOperationNone; 
} 

顯然有更多的全貌,但這則hitTest:基於方法迄今爲我工作。我懷疑如果一個人使用像NSTableView或NSOutlineView這樣的基於多NSCell的控件,這會稍微複雜一些,但毫不奇怪,這些控件都有自己的拖動處理方法。

希望這可以幫助別人。