I've understood the fly-weight approach of cell-based NSTableView and I think I understand the differences with NSCollectionView.Differences between (cell-based) NSTableView and NSCollectionView
However, a bit less obvious is the differences between view-based NSTableView and NSCollectionView.
With NSCollectionView's flexibility in displaying its items (i.e. in a grid layout) which could emulate a tableView's list (a grid with maximum one column) and excluding personnal preferences, why would someone choose (View-based) NSTableView over NSCollectionView?
Update: (Recycling of views is implemented since El Capitan)
NSCollectionView doesn't use view recycling. This means that a view will be created for every single collection view item, regardless of whether the view is on screen or not. This can wreck your performance with large data sets. A view based NSTableView uses view recycling and is very efficient, as it recycles a limited number of cells instead of creating new ones for every item. Not to mention that NSCollectionView is overall a poorly written and poorly documented class.
Related
What is the main difference between cell based and view based tableviews in Cocoa.
The understanding I have is cell based tableviews are basically used for displaying strings and view based are for custom cells.User events such as dragging rows, selection etc can be handled in view based.
cell based tableviews use objectValueForTableColumn: method and view based tables use viewForTableColumn: method.
Is my understanding correct?. Or is any other design concerns between these table views. When to go for cell based and when to go for view based.
Thanks in advance
short answer:
A cell can contain only one UI element like a text cell, image view cell, button cell and a few more. The customization ability is quite poor.
A view can contain multiple UI elements as well as other views. The customization ability is almost infinite.
Apple recommends to use always view based table views
NSCell is a lighter weight object and was a solution when it was a concern to have too many NSView objects.
Think more than a decade ago.
Cells are deprecated.
Use views.
In iOS, you have a concept of View Containment, is there such things in OSX?
Basically I want to create multiple nsviewcontroller each managing a specific view. I'd have a MasterViewController with a menu on the left (like ITunes), each time the user click on an item on the left, it would load the correct nsviewcontroller to display it's view.
Any tips to achieve what I need is appreciated
Thanks,
As of OSX 10.10 there is, watch Storyboards and Controllers on OS X.
Comment.
NSViewController did basically nothing (other that load NIBs) for years, I'm glad to see that it finally got from attention. Certain people in the Cocoa crowd here have a snotty attitude about the view controller programming style; I've asked questions like this before and had the "are you a iOS newbie coming to Cocoa" response. That's something that I never understood, it's a great model for containment, and reuse.
The main difference between OS X and iOS is that on an iOS device you have only one "window". On OS X there are desktops that can contain many windows that you can view and interact with at the same time.
In general, it sounds like you are trying to create an NSWindow that contains a single-column NSTableView for your list of choices on the left, and some other view that will display the detail of the selection on the right. It's common to place these within a vertical NSSplitView so the user can adjust their relative widths, but they could also stand on their own, as two separate subviews within the window's main view.
You typically use an NSArrayController to manage the list contents and track which particular item is selected. For your detail view on the right, you would use a single NSView with NSControl subviews that display values bound to the array controller's selected object.
If the data structure varies among your objects, swap in or show/hide various subviews as needed for the different types of data the particular selected object represents. You can use the "Conditionally Sets Hidden" binding option to automatically hide controls for which there is no applicable keyed value.
Alternatively, if there's a fixed number of objects in your list and their structures are all quite different from one another, then you may wish to use a tabless NSTabView that has a separate tab with its own custom view for each of your objects. Observe when the selection changes in your list, and select the appropriate tab accordingly.
As per apple documentation drag and drop NSTableView delegate methods are called only for cell based TableViews not for View based. So there is no way to do reordering of rows using drag & drop for view based NSTableView?
I have created a small sample project which has an NSOutlineView where you can add and remove items as well as reorder them. This is not an NSTableView but the implementation of the Drag & Drop protocol is basically identical.
I implemented drag and Drop in one go so it's best to look at this commit.
Drag and drop delegate methods get called fine in a view based NSTableView. There is a great presentation from WWDC '11 on view based table views, and it includes a lengthy discussion about drag and drop. Worth watching.
Link here - requires a login.
I have an NSCollectionView that I want to accept items dragged from elsewhere in my application.
I implement collectionView:validateDrop:proposedIndex:dropOperation: and collectionView:acceptDrop:index:dropOperation: in the collectionview's delegate and register for the appropriate dragged types. Both methods get called fine when I drag the appropriate types, but I don't get a blue focus ring over the collectionview indicating a valid drag.
Have tried both the collection view and its containing scroll view on Default and External settings for the focus ring. Both are just the standard non-derived Cocoa classes. Wondered if there was anything else I should try. Surely it isn't necessary to subclass NSCollectionView for this?
Thanks
Chris
Focus rings are not typically the correct way to provide feedback about drag destinations. Every view does it slightly differently. NSTextView shows the insertion bar. NSTableView shows a blue line in between rows for Before drop operations, and shows a bezel around the row for On drop operations. (See NSTableViewDropOperation)
NSCollectionView shows a "gap" between existing subviews to show where the items will be dropped for Before drop operations, and it will set the selected property on NSCollectionViewItem to YES for On drop operations. (Note: NSCollectionViewItem doesn't do anything by default to visibly represent the selected property. You must implement that yourself.)
Since NSCollectionView's feedback uses existing subviews only, it appears there isn't any feedback at all for empty NSCollectionView's. You would need to subclass to provide this behavior yourself. You could also file a bug to request that NSCollectionView do this itself.
I am learning Cocoa and trying to create an application for Mac that displays a simple book list. Each book is an NSView with its cover image, title and author. I want to present this list as a NSTableView with a single column and a book view in each cell. However i can't yet figure out how to display a custom view inside a table cell in interface builder or programmatically. Any tips would be very appreciated :)
Inso.
If all of your "book views" are the same size, why not use NSCollectionView / NSCollectionViewItem? It's a much cleaner solution (provided they're all sized the same).
Assuming a collection view wouldn't be a better solution, what you need to do is to write a custom cell. The column owns exactly one such cell, which the table view will use to draw the column's value for each row.
(If you came from the iPhone, yes, this is completely different from UITableView. Each NSTableColumn has exactly one cell, which it uses for every row.)
If you're using your NSView class somewhere else, then you could make it into a subclass of NSControl and have it use another instance of the same cell class. Like most controls, all the real work would be done by the cell, which enables you to reuse that behavior in multiple controls (your single control and your table view).
See Control and Cell Programming Topics for more info.
Apple added view-based table views in Lion, so you should be able do this natively with NSTableView, now.
(You still can't put an NSView in an NSCell—that wouldn't make sense. But you can have views instead of cells in a table view.)