Cocoa: How to make table view draw custom views in each cell - cocoa

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.)

Related

View and Cell based NSTableView

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.

How to correctly add NSComboBox to view-based NSTableView in Interface Builder

I'm basically asking how do you correctly add a Combo Box to a Table View with correct layout i.e. so that appears as if you were adding a ComboBox cell to a cell-based Table View. Currently when I add it to the Table Cell View it doesn't fit (bottom half chopped off) and doesn't behave as its supposed i.e. focus ring is messed up, arrows messed up, not aligned correctly.
I have searched the net couple of times over and funny enough I haven't found an answer to this question. If I don't find a solution I might have return to good old cell-based table views.
If the combo box doesn't fit, you need to increase the height of the NSTableCellView. This is done in Interface Builder or, if implemented, in the NSTableViewDelegate method tableView:heightOfRow:.

Prototype Cells in UITableView not on top

It's really strange. The Prototype-Cell in my second UITableView isn't on top as it should be:
If I start moving it, than it's on top again, but after i drop it on my View, it is still in this strange way.
How can I change that?
As you see, the first Cell is okay, but the second isn't.
Well, it's difficult to understand using only an image, but I will give you some possible causes for that:
Have you applied a table header view by accident in the second table view? If you did, removing it will be the solution
Have you applied the proper view constraints in the table view and its cells?
If I were you, I would not try to embed two UITableViews in the same view controller this way, especially since you use storyboards with iOS 7. What I would do is to use embed segues. Just drag a container view for each of your view table views, and connect their embed segues to their appropriate table view controllers ( you need to create in the storyboard those, two). That way, you can set the constraints much easier, separate the logic between the two and have a cleaner interface. You can do that and see if that helps.

Create tables with mixed content

I must create a table with five rows. The first row contains a label and switch button, the remaining 4 rows contain simply a label.
This table has not to be modified.
Then, I used a storyboard to design table as specified above; now, I need a function to manage user's pressure on any row. Anyway, if I associate an UITableViewController class to my storyboard and run simulator, the table appears empty, because the methods of controller to fill rows have not been implemented. But I don't want to implement them, since my table has already been designed through the storyboard.
How can I design a controller simply managing my storyboard as it is, without defining functions trying to modify the structure I designed, but allowing to handle user's interactions as well?
If I loaded my storyboard into an UITableViewController through the use of function instantiateViewControllerWithIdentifier, would I have my table as I designed it, giving labels/table/button an identifier? How could I manage user's interaction in this case? how could I access the table and its field/row numbers?
Alternatively, how could I create my table programmatically, with a label and a button on first row?
If you need to easily use the standard switch cells, label cells, and other standard UI cells, then I'd strongly recommend you check out the free Sensible TableView framework. Should save you a ton of time.
The tableview you designed with storyboard has a custom class, it's your view controller. Even you've finished the design of your tableview with storyboard, you still have to implement the delegate & datasource methods in your view controller. In your case, you need to implement "tableView:numberOfRowsInSection" to return 5, and "tableView:heightForRowAtIndexPath" if your custom cells have different height.
You should create custom tableview cells to manage user's interaction. Design the cells in storyboard, implement the logic in your custom UITableViewCell classes. Set the cell's custom class to your custom UITableViewCell classes. Pass users' interaction events to your UITableViewController with delegate.
Create UITableView programmatically is not very different. Create an UITableView and add it as subview. Make sure you set self as the delegate and datasource of the tableview. Implement all the delegate & datasource methods in your ViewController. Create a custom UITableViewCell with button and label programmatically, and return it in "tableView:cellForRowAtIndexPath" when "indexPath.row == 0"

Is there a concept of viewcontroller containment in NSViewController

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.

Resources