NSTableView delegate inside Nib - objective-c

I have a NSWindowController as part of the work flow with NSDocument. The NSWindowController has an associated xib with a couple of NSTableViews. The datasource for these tableviews is a model defined by the NSDocument. I seem to be missing some information on setting up the outlets. If I setup all the outlets within IB, the datasource(s) are created at the time the nib is instantiated with their default init methods, which don't know about the model. By the time awakeFromNib is called, the datasource has already been queried by the tableview (numberOfRowsInTableView). My work-around is to not hook up the outlets for datasource. I get the model information in setDocument and set the delegates in windowDidLoad. This seems to work. How do I pass around a data model when setting the tableview datasource with IB? Since the outlets are not created when init is called (within the tableview datasource), how would I call out to get the model?
Thanks in advance.

There's an explicit note in the NSTabelView documentation:
Important: It’s possible that your data source methods for populating
the table view may be called before awakeFromNib is called if the data
source is specified in Interface Builder. You should defend against
this by having the data source’s numberOfRowsInTableView: method
return 0 for the number of rows when the data source has not yet been
configured. In awakeFromNib, when the data source is initialized you
should always call reloadData on the table view.

Related

awakeFromNib called multiples times

I have an NSViewController associated to a NIB, which itself contained some NSView and NSButton. I was using awakeFromNib to initialize some model classes. It worked just fine, until I added a view-based NSTableView. Now, awakeFromNib is called multiples times. Why is it the case ? and what reliable method could I use to initialize my model classes ? Thanks in advance.
If your NIB file contains a view which is then to be used and instanciated multiple times for your view-based NSTableView then each of these view's instances will receive an awakeFromNib call/message.
Similar question.

Subclass UITableViewController, where do I set it up within the UIViewController?

I have a UIViewController, with a UITableView which takes up half the screen.
I also have a subclassed UITableViewController, but I can't figure out how I would associate the subclassed UITableViewController with my table?
It is not clear from your question exactly why you are trying to create a UITableViewController and a UIViewController in this case. Do you have 2 different tables you are trying to control? Or are you trying to do something special to have 2 different controllers managing different parts of a view/subview hierarchy?
Typically, the table for a UITableViewController is created automatically or within a NIB file. From the UITableViewController documentation:
If a nib file is specified via the initWithNibName:bundle: method
(which is declared by the superclass UIViewController),
UITableViewController loads the table view archived in the nib file.
Otherwise, it creates an unconfigured UITableView object with the
correct dimensions and autoresize mask. You can access this view
through the tableView property.
So you would usually not need to associate your subclassed UITableViewController with its table because that is taken care of for you.

Connect UITableView DataSource/Delegate to base UIViewController class

I'm attempting to connect my UITableView's DataSource and Delegate to my ViewController's base class via the storyboard. I Was able to connect my IBActions and IBOutlets easily, but this is proving trickier.
Is the correct method to instantiate the delegate/datasource methods then call the same methods on super?
TIA
Xcode will type-check the objects you attempt to connect. So there are two pre-requisites:
An object of your class must "be present" in the storyboard, which usually involves setting a custom class on a UIViewController in the inspector
The class of your object must declare that it conforms to the correct protocols before you make the connections.
If those two criteria are met, you should be able to ctrl-click on the UITableViewController, and drag from these connections to an object of your class, either in the storyboard or in the list of objects on the left.
EDIT: I have added a picture of setting the delegates via the two-step method of ctrl-clicking the table view, then dragging from the popover to the protocol-conforming view controller. This technique works with both the list view on the left as well as the graphical representations in the workspace.

What awakeFromNib really is?

I'm just a newbie of Objective C iPhone programming... I see a lot of codes that contains method named "awakeFromNib".. What does it really mean? how and when and where to call this method?
Thanks...
awakeFromNib is called for objects (views, controllers, etc.) that are being archived in xib/nib files. This basically means that xib/nib was unarchived, all connections (IBActions/IBOutlets) for all objects are made and you have a working object graph.
I use it when I have a custom view class that I gave to a certain view in my xib.
You don't call it. After nib file load, every view inside of it, be it button, UIView or something else, calls awakeFromNib from their respective class automatically. You override this method for setup and layout, as you would do with init method if you were creating a subview programmatically.

The relationship between UIViewController and UIView

I'm trying to understand how these two are connected. Every time you make a UIViewController does it also automatically come with its own UIView?
Also are these from Cocoa or Objective-C?
UIViewController is a Cocoa Touch class built for the purpose of managing UIViews. It expects to have a view hierarchy, but you don't "automatically" get a view (this is slightly inaccurate; see edit below). Usually you will obtain views by calling initWithNibName on your view controller.
There is some built-in magic in Interface Builder which knows that if File's Owner is a UIViewController (or subclass), there is a property called view. That's about it.
Once you have linked a view controller and a view, the view controller does a fair amount of work for you: it registers as a responder for view touch events, registers for device rotation notifications (and handles them automatically, if you wish), helps you take care of some of the details of animation, and handles low-memory conditions semi-automatically.
Edit: correction—if you don't call initWithNibName or set the view property manually, the view property getter will invoke loadView if view is nil. The default implementation of loadView will see if you've set nibBundle and nibName and attempt to load the view from there (which is why you don't have to call initWithNibName, most of the time), but if those properties aren't set, it will instantiate a UIView object with default values. So technically, yes, it does automatically come with its own UIView, but most of the time that's of little value.
UIViewController doesn't automatically come with a view. You have to make a view in the -loadView method. By default, this loads the view from the nib file you've specified. You can also override this method to make a custom view if you prefer not to use a nib.
Also, the view is not created right when the UIViewController is created. UIViewController uses a technique known as lazy-loading to defer the creation of a view until the view is actually accessed for the first time.