天道酬勤,学无止境

How do i implement Drag and drop with NSOutlineVIew

I have two NSTableViews on screen; I just want to drag a row from one table to the other table. I see lots of tips here and there but I do not see a complete example and I'm a bit confused. I saw examples that were totally different to Apples sample apps TableView playground and drag and drop outlineView.

I decided to use Apples method, but now im stuck. TableView playground implement these methods in their model object.

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

I dont understand how to set these up. For the 1st method i returned an array with string @"com.mycompany.myapp.mypasteboardtype"as suggested in this question.

What should i put for the 2nd method? My model is a custom object that has a number of strings, Arrays, and dictionary variables. I also do not understand the 3rd method. I wish there was some example i could see that does a simple drag from one table to another with a custom model object.

EDIT: My implementation based on response below

-(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;
}

评论

What should i put for [pasteboardPropertyListForType:]? My model is a custom object that has a number of strings, Arrays, and dictionary variables.

It depends on what type you're being asked for.

If it's your own custom type that you made up, you can put whatever you want. Really—if it's your type that you've invented, you can return whatever you want here, as long as it's a valid property list. You just have to make sure that your paste/drop code (pasteboard reading) is expecting the same stuff.

If you want to support internal drags (reordering and/or relocation within the hierarchy), you should have at least one custom type that identifies the object so that you can look up the same object when accepting the drop (in order to move it rather than duplicate it). For a Core Data object, you might use the absolute string of the object's identifying URI.

If you want to support dragging to other applications, you should have at least one non-custom type that those other applications will recognize. What type(s) you support will depend on what your model represents: if they're images (or recipes for creating them, such as stacks of layers), you could support PNG, TIFF, JPEG, etc.; if they're contacts, you could support vCard; if they're text, you could support plain text and/or RTF and/or HTML and/or WebArchive and/or Microsoft Word; etc.

You return an array of the types that this object can be turned into from writableTypesForPasteboard:; afterward, pasteboardPropertyListForType: must look at what type it was asked for and return a property list of that type.

For most external formats, pasteboardPropertyListForType: must return a data object. For your own custom formats, it's usually either a dictionary or an array of dictionaries, although, as I said, the only real requirements are that it must be a plist of some sort and your reading code must be able to understand it.

I also do not understand [writingOptionsForType:pasteboard:].

You must return a bit mask indicating when and how you will write the type to the pasteboard. The available options are documented.

Currently, there's only one: You can promise the data. This means that the pasteboard will not immediately ask you for the data; it will wait until the user pastes or drops it somewhere (or the data is otherwise requested by any application—e.g., a poorly-written drop validation method could request the data and examine it during validation, rather than drop acceptance). Only then will it call pasteboardPropertyListForType: for that type. (And this is a per-type option; you can choose to promise some types but not others.)

Promising is great for data that is expensive to compute and/or store; for example, a compressed archive (compute) or a large image (store).

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • NSTextField not calling delegate when inside an NSTableCellView
    I have a fairly vanilla Source List (dragged out from the Object Library) in my app, with an NSTreeController as its data source. I set the NSTextField inside the DataCell to be editable, but I want to be able to turn that off for some cells. The way I figured you would do this, is with a delegate for the NSTextField, but none of the delegate methods I've tried get called. Is there something I'm missing? I have the delegate set with an outlet in my XIB, and it happens to be the delegate to the owner NSOutlineView, as well, implementing both the NSOutlineViewDelegate and NSTextFieldDelegate
  • 在拖放过程中在 NSTableView 中打开一个间隙(Opening a gap in NSTableView during drag and drop)
    问题 我有一个简单的、单列的、基于视图的 NSTableView,其中包含可以拖动以重新排序的项目。 在拖放过程中,我想在鼠标下方的位置打开一个用于放置物品的间隙。 当您拖动以重新排序曲目时,GarageBand 会执行类似的操作(视频在这里:http://www.screencast.com/t/OmUVHcCNSl)。 据我所知,在 NSTableView 中没有内置支持。 有没有其他人尝试将此行为添加到 NSTableView 并找到一个好的解决方案? 我想过并尝试了几种方法,但都没有取得多大成功。 我的第一个想法是通过在我的数据源的-tableView:validateDrop:...方法中发送-noteHeightOfRowsWithIndexesChanged:在拖动过程中将鼠标下方行的高度加倍,然后在-tableView:heightOfRow:返回正常高度的两倍。 不幸的是,据我所知,NSTableView 在拖放过程中不会更新其布局,因此尽管调用了noteHeightOfRowsWithIndexesChanged: ,但实际上并未更新行高。 请注意,我使用的是基于视图的 NSTableView,但我的行并不复杂,如果这样做有助于实现这一点,我就无法移动到基于单元格的表格视图。 我知道一种简单的内置功能,可以在拖动完成后为放置的项目设置间隙动画。
  • 在NSTableView上拖放重新排序行(Drag & Drop Reorder Rows on NSTableView)
    问题 我只是想知道是否有一种简单的方法来设置NSTableView,以使其无需编写任何粘贴板代码即可对行进行重新排序。 我只需要它能够在一个表中内部执行此操作。 我没有编写Pboard代码的问题,只是我非常确定我看到Interface Builder在某个地方对此有一个切换/看到它在默认情况下可以工作。 当然,这似乎是一项足够普通的任务。 谢谢 回答1 如果您查看IB中的工具提示,将会看到您所引用的选项 - (BOOL)allowsColumnReordering 控件,然后,列重新排序。 我认为除了用于表视图的标准拖放API之外,没有其他方法可以执行此操作。 编辑: (2012-11-25) 答案是NSTableViewColumns的拖放重排; 虽然这是当时公认的答案。 现在似乎已经过去3年了,它似乎并没有正确。 为了使信息对搜索者有用,我将尝试给出更正确的答案。 没有设置允许在Interface Builder中对NSTableView行进行拖放重新排序。 您需要实现某些NSTableViewDataSource方法,包括: - tableView:acceptDrop:row:dropOperation: - (NSDragOperation)tableView:(NSTableView *)aTableView validateDrop:(id <
  • 基于 NSTableViewCell 的上下文菜单(context menu based on NSTableViewCell)
    问题 我想将上下文菜单放在NSTableView 。 这部分完成了。 我想做的是根据右键单击的单元格的内容显示不同的菜单条目,并且不显示特定列的上下文菜单。 这是: 第 0 列和第 1 列没有上下文菜单 所有其他单元格应该有这样的上下文菜单: 第一个条目:“删除” samerow.column1.value 第二个条目:“保存” samecolumn.headertext 希望问题很清楚.. 谢谢 -编辑- 右边的是上下文菜单对于任何给定单元格的外观。 回答1 有一个代表! - 无需子类化 在 IB 中,如果您将NSTableView拖到您的窗口/视图上,您​​会注意到表格有一个menu出口。 因此,实现上下文菜单的一种非常简单的方法是将该出口连接到存根菜单,并将菜单的委托出口连接到实现NSMenuDelegate协议方法的对象- (void)menuNeedsUpdate:(NSMenu *)menu 通常,菜单的委托是为表提供数据源/委托的同一个对象,但它也可能是拥有该表的视图控制器。 查看文档以获取有关此的更多信息 你可以在协议中做很多聪明的事情,但一个非常简单的实现可能如下所示 #pragma mark tableview menu delegates - (void)menuNeedsUpdate:(NSMenu *)menu { NSInteger clickedrow
  • NSOutlineView spring loading exits over NSImageView but not NSButton
    I have an NSOutlineView subclass that implements the NSSpringLoadingDestination. The outline view is populated with NSTableCellViews. Each table cell view has an NSTextField and NSImageView. It looks just like the name column in the Finder window: icon and text. When I drag a row over the text field in another row everything works fine. When the cursor goes over the NSImageView, however, the spring loading exits. The outline view also loses the highlight for that row. If I replace the image view with an NSButton containing the image, the spring loading does not exit. And the outline view
  • 如何在基于视图的NSOutlineView中自定义公开单元(How to customize disclosure cell in view-based NSOutlineView)
    问题 我正在尝试在基于视图的NSOutlineView中自定义显示箭头的外观。 我看到建议使用 - (void)outlineView:(NSOutlineView *)outlineView willDisplayOutlineCell:(id)cell forTableColumn:(NSTableColumn *)tableColumn item:(id)item 委托方法来实现它。 问题是由于某种原因未调用此方法。 我有2个自定义单元格视图-一个用于项目,第二个用于标题项目。 可能不是基于视图的大纲视图不调用此方法吗? 可能是Lion中的某些东西坏了吗? 请说明一下。 回答1 此答案是在考虑到OS X 10.7的情况下编写的,对于较新版本的OS X / macOS,请参阅WetFish的答案 该方法不会被调用,因为它仅与基于单元格的轮廓图相关。 在基于视图的轮廓图中,公开三角形是可展开行的行视图中的常规按钮。 我不知道将它添加到何处,但确实如此, NSView的didAddSubview:方法恰好可以处理将视图添加到其他地方的情况。 因此,子类NSTableRowView和重写didAddSubview:如下所示: -(void)didAddSubview:(NSView *)subview { // As noted in the comments, don't
  • 展开从数据源加载数据的NSOutlineView的所有项(Expanding all items of a NSOutlineView that loads data from a data source)
    问题 首先,我是可可开发的新手,所以我想我可能会尝试以错误的方式进行操作,但是这里有: 我有一个NSOutlineView ,它从NSOutlineViewDataSource实现中加载数据。 我希望所有项目在加载后都可以扩展,但是我似乎找不到在数据完成加载后触发的事件,因此我可以向其发送[outlineView expandItem: nil expandChildren: YES] 。 我调查了NSOutlineViewDelegate协议,但找不到适合此调用的位置。 解决此问题的最佳方法是什么? 回答1 通常,我喜欢在表单中执行以下操作-awakeFromNib或任何其他启动回调 dispatch_async(dispatch_get_main_queue(), ^{ [self.outlineView expandItem:root expandChildren:YES]; }); 这将在运行循环的当前循环结束时将执行块放入队列,因此将在所有初始化完成后执行该块。 无需设置任何人为延迟。 回答2 我想出的最好的解决方案是编写一个方法,该方法在延迟为零之后扩展NSOutlineView 。 - (void)windowDidLoad { [super windowDidLoad]; [self performSelector:@selector
  • 在 Xamarin Studio 中以编程方式创建 NSView(Create NSView programmatically in Xamarin Studio)
    问题 我试图找到我之前问过的这个问题的解决方案:在 Xamarin.Mac 应用程序中填充 SourceList 我目前正在尝试实现NSOutlineViewDelegate的GetView方法,以查看是否可能在我拥有的 OutlineView 中创建一些文本。 但是我一直在尝试向 NSView 对象添加内容。 当我查看示例 OutlineView(默认情况下,将它拖到窗口上时获得的那个),每个项目都有一个TableCellView 。 结构看起来像这样(首先是标题,然后是常规项目): Table Cell View Static Text - HEADER CELL Text Field Cell - HEADER CELL Table Cell View Image View Image Cell Static Text - Table View Cell Text Field Cell - Table View Cell 到目前为止,我的方法是这样的: public override NSView GetView (NSOutlineView outlineView, NSTableColumn tableColumn, NSObject item) { var navigation = item as Navigation; var cell = new
  • 没有NIB的基于视图的NSOutlineView?(View-based NSOutlineView without NIB?)
    问题 NSOutlineView是NSOutlineView的子NSTableView 。 目前, NSTableView支持两种实现。 基于单元格。 基于视图。 要使OSX 10.8 Finder样式的侧栏(具有自动的灰色Icon样式),需要使用带有源列表突出显示样式的基于视图的表视图。 对于NIB,这是典型的工作。 没什么难的。 (请参阅SidebarDemo)但是我要避免使用任何NIB或Interface Builder。 我想纯粹以编程方式制作侧边栏。 在这种情况下,我有很大的问题。 AFAIK,无法提供特定单元的原型视图。 当我打开.xib文件时,我看到<tableColumn>包含<prototypeCellViews> 。 这指定了将用于该列的视图。 我找不到如何使用公共API以编程方式设置此设置的方法。 作为一种解决方法,我尝试使用-[NSTableView makeViewWithIdentifier:owner:]和-[NSTableView viewAtColumn:row:makeIfNecessary:]手动制作单元格,但是它们都不返回视图实例。 我创建了一个NSTableCellView ,但是它没有图像视图和文本字段实例。 我也尝试设置它们,但是字段被标记为assign因此实例立即被释放。 我试图通过强制保留它们来保留它,但是它不起作用。
  • Why is my NSOutlineView datasource nil?
    This is a follow-on question from my previous one relating to why my managedObjectContext was returning to nil. I thought the direction of the question would get buried in the old one. I now get my mangedObjectContext to not return nil and when performing [outlineView reloadData], nothing at all happens to my outlineView. I tried selectively removing parts of the code that are intended to update the outlineView to see if anything changes and the answer is no. I've since found out (after I wrote this question originally) that my dataSource association is disappearing at some stage. Notes: the
  • View-based NSOutlineView without NIB?
    NSOutlineView is a subclass of NSTableView. And currently, NSTableView supports two implementations. Cell-based. View-based. To make OSX 10.8 Finder style side bar (with automatic gray Icon styling), need to use view-based table view with source-list highlight style. With NIBs, this is typical job. Nothing hard. (see SidebarDemo) But I want to avoid any NIBs or Interface Builder. I want make the side bar purely programmatically. In this case, I have big problem. AFAIK, there's no way to supply prototype view for specific cell. When I open .xib file, I see <tableColumn> is containing
  • 如何在Cocoa / IB中实现类似于Mail / iTunes / Finder / etc的边栏?(How would one implement a sidebar similar to Mail/iTunes/Finder/etc in Cocoa/IB?)
    问题 我认为标题几乎说明了一切...我正在寻求实现类似于上述所有程序中使用的标准OS X侧边栏的界面,并且我想知道是否有人对最简单的方法有任何想法要做到这一点,即关于在左侧选择窗格中使用哪种视图。 真的,我认为我什至不需要苹果应用程序中的分层组件,而只需要一个外观漂亮的平面选择列表即可确定右侧窗格中显示的内容。 明显的开始是垂直拆分布局视图,但是除此之外,我不确定要去哪里。 只有一列或类似内容的集合视图? 回答1 我已经完成了一些使用类似设置的应用程序。 我通常使用NSSplitView,在左窗格中只有一列NSTableView。 不要忘记禁用标题,并将其显示为“源视图”样式。 如果您想要显示三角形,那么您将要使用NSOutlineView而不是NSTableView,但是至少首先,我会坚持使用简单的NSTableView。 我还使用的一种模式是使NSTableView略短于NSSplitView,并在底部具有按钮(添加,删除等)。 我通常围绕Core Data构建程序,因此很容易将它们连接到创建/删除对象的方法,然后将NSTableView绑定到对象数组。 回答2 在Leopard中添加了对这种事情的直接支持。 这称为“源列表”。 请参阅AppKit发行说明。 在文档中搜索NSTableViewSelectionHighlightStyleSourceList。 或者
  • How to implement drag and drop in cypress test?
    I am struggling to test drag and drop with Cypress and Angular Material Drag and Drop. So the goal is to move "Get to work" from Todo to Done. I have created the following test, that should make it easy for you to reproduce: You can play with the Stackblitz here. describe('Trying to implement drag-n-drop', () => { before(() => { Cypress.config('baseUrl', null); cy.viewport(1000, 600); cy.visit('https://angular-oxkc7l-zirwfs.stackblitz.io') .url().should('contain', 'angular') .get('h2').should('contain', 'To do'); }); it('Should work, based on this https://stackoverflow.com/a/54119137/3694288'
  • Qt 4.x:如何将拖放到桌面或文件夹中?(Qt 4.x: how to implement drag-and-drop onto the desktop or into a folder?)
    问题 我已经编写了一个使用Qt 4.x用C ++编写的文件传输应用程序...它登录到服务器,向用户显示服务器上可用文件的列表,并允许用户上载或下载文件。 一切都很好; 您甚至可以从桌面(或从打开的文件夹)中拖入文件,然后在将文件图标拖放到server-files-list-view中时,所拖放的文件将被上载到服务器。 现在,我也要求采取相反的行动...我的用户希望能够将文件拖出server-files-list-view并拖到桌面上,或拖到打开的文件夹窗口中,并具有文件下载到该位置。 这似乎是一个合理的要求,但是我不知道如何实现它。 当图标放到桌面或打开的文件夹窗口中时,Qt应用程序是否可以找到与“放置事件”发生位置相对应的目录? 理想情况下,这将是基于Qt的平台中立机制,但是如果不存在,则适用于MacOS / X和Windows(XP或更高版本)的平台特定机制就足够了。 有任何想法吗? 回答1 看一下QMimeData及其文档,它具有虚拟功能 virtual QVariant retrieveData ( const QString & mimetype, QVariant::Type type ) const 这意味着要拖到外面,您可以相应地实现此功能 class DeferredMimeData : public QMimeData { DeferredMimeData
  • Example of how to implement a view-based source list (NSOutlineView) using Cocoa Bindings?
    Has anybody found a clear, concise example or guide on how to implement a source list using the view-based NSOutlineView introduced in Lion? I've looked at Apple's example project, but without any sense of direction or explanation, I'm finding it difficult to grasp the concept of exactly how they work. I know how to use the excellent PXSourceList as a fallback, but would really like to start using view-based source lists instead if at all possible.
  • 如何在 NSOutlineView 中显示不确定的 NSProgressIndicator?(How to display indeterminate NSProgressIndicator in the NSOutlineView?)
    问题 我需要显示项目子项的加载进度。 请告知如何像在邮件应用程序中那样实现进度指示器: 大纲视图中的进度指示器 http://www.quicksnapper.com/files/10513/5329281414A48CEBA2FFE0_m.png PS 这里是使用指标子视图的源代码:http://snippets.dzone.com/posts/show/7684 回答1 这比它应该的更难,因为 Apple 没有提供 NSProgressIndicatorCell。 虽然表格和大纲视图支持在其中显示自定义单元格的想法,但它们不能轻松支持自定义子视图。 所以技巧就变成了,你如何获得一个完整的 NSProgressIndicator 视图来在你的窗口中的所需位置显示和动画,而不能实际安装在表视图行中? 我使用的技巧是从字面上安装 NSProgressIndicator 作为大纲或表格视图本身的子视图。 要找到添加子视图的位置,使其看起来像“在行中”,请使用 frameOfCellAtColumn:row: 方法。 然后,您可以将进度指示器放置在大纲视图的该位置内。 完成旋转进度指示器后,您可能不想再显示它,因此只需将其从其超级视图中删除并丢弃即可。 您需要确保在进度指示器上设置所需的自动调整大小标志,以便在调整大纲视图大小时/如果调整大小,它会以正确的方向浮动。
  • View-based NSOutlineview selection gradient
    I'm still struggling with the view-based NSOutlineView in my little Cocoa application. I'm trying model my OutlineView after the finder one. When the Finder OutlineView loses focus (e.g. clicking any folder on the right side), the selected row (e.g. Desktop) stays selected with the bright blue gradient and does not change to the inactive blue-grey gradient. I'd like to duplicate this behaviour in my application. In a not view-based OutlineView I was able to subclass NSOutlineView and reimplement (void)highlightSelectionInClipRect:(NSRect)clipRect, so that each highlighted row could be supplied
  • Implement drag-and-drop like in Scene Builder
    I'm building an application in JavaFx 2.2 which consist in a splitpane with a panel of component on the left side and a working sheet on the right side. Basically what i would like to do is a simple wysiwyg editor where you drag component from the left to the right, then arrange them on the right side. I've spent the last couple of days trying to implement the same drag-and-drop feature that has SceneBuilder, without luck.. Following the sample at http://docs.oracle.com/javafx/2/drag_drop/HelloDragAndDrop.java.html i've managed to get a drag-and-drop working but i can't find any way to change
  • Implementing drag-drop from Chrome on my .NET Windows form
    Google Chrome has a handy feature where I can click a download link and drag it into a Windows Explorer window, and then drop. After dropping, Chrome then downloads the file and it appears where I dropped it. I would like to be able to drop from Google Chrome into my application, but it seems it isn't so simple. I have a DataGridView called gridFiles, and the following code: Private Sub gridFiles_DragDrop(ByVal sender As Object, ByVal e As System.Windows.Forms.DragEventArgs) Handles gridFiles.DragDrop If e.Data.GetDataPresent(DataFormats.FileDrop) Then Dim DroppedFiles() As String = e.Data
  • View-based NSOutlineView header cell font issues
    I'm currently trying to use a new view-based NSOutlineView in my Cocoa app. As I'm not using bindings, so I implemented all required delegate and datasource methods in my controller. In interface builder I've added a NSOutlineView with a highlighting set to SourceList and Content Mode set to View Based. Thus, there were two default table cell views provided (one Header cell with HeaderCell set as identifier and one data cell with DataCell set as identifier) This is what it looks like in interface builder, header cell views correctly show a grey-blue textField while data cell views have a image