ipm*_*mcc 5 cocoa drag-and-drop nsview cocoa-bindings
直到今天,我还没有机会使用除NSWindow之外的任何东西作为NSDraggingDestination.当使用窗口作为一个通用的拖拽目的地时,NSWindow会将这些消息传递给它的委托,允许你处理drop而不用子类化NSWindow.
该文件说:
尽管NSDraggingDestination被声明为非正式协议,但您创建的NSWindow和NSView子类只需要实现那些相关的方法.(NSWindow和NSView类为所有方法提供私有实现.)窗口对象或其委托可以实现这些方法; 但是,如果两个地方都有实现,则委托的实现优先.
今天,我有一个带有两个NSTextFields的窗口,我希望它们具有不同的放置行为,我不想在窗口中的任何其他位置允许放置.我解释文档的方式,似乎我要么必须子类化NSTextField,要么在窗口的委托上创建一些巨大的意大利面条件下拉处理程序,它们针对每个视图点击检查draggingLocation,以便选择不同的drop-area行为.每个领域.
基于NSWindow-delegate的集中式丢弃处理程序方法似乎在任何情况下都是繁重的,在这种情况下,您只有少量的drop目标视图.同样,无论情况如何,子类化方法似乎都很繁琐,因为现在丢弃处理代码存在于视图类中,因此一旦接受了丢弃,您就必须想出一些方法来将丢弃的数据封送回模型.该绑定文档提醒你关闭试图通过编程设置UI价值驱动绑定.所以现在你也被困在那里.
所以我的问题是:"真的!?那些是唯一随时可用的选择吗?或者我在这里错过了一些直截了当的东西?"
谢谢.
经过一番研究后,看来"是的,真的,你的两个选择要么是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;
}
Run Code Online (Sandbox Code Playgroud)
显然,整体情况还有更多,但这种基于hitTest:的方法到目前为止对我有用.我怀疑,如果使用基于多个NSCell的控件(如NSTableView或NSOutlineView),这会稍微复杂一些,但不出所料,这些控件有自己的拖动处理方法.
希望这有助于其他人.