What object should implement NSCollectionViewDelegate? - objective-c

I have a subclassed NSCollectionView that is created in Interface Builder and is bound to an array.
I need to implement some of the delegate classes from NSCollectionViewDelegate but I'm kind of stumped as to what class to designate as the delegate.
Do I just create a random NSObject and designate it as the delegate? Do I create an NSViewController and designate that as the delegate—but if so, since the Collection View isn't being created programmatically, how do I tie the NSViewController to the Collection View?
Any pointer to a good document that would explain stuff like this in Mac app architectural decisions would be a great bonus.

It is common, but not mandatory, to make a view controller also be the delegate of the underlying view object. However, you can also make a new class as you suggest and use that. If that works for your overall architecture, do that.

What kind of object is the File's Owner of the NIB? Most often, a NIB should be loaded and owned by either an NSWindowController or NSViewController (or subclass of one of those). That controller would typically be responsible for everything in the NIB, so it would be the delegate.
If it makes sense, you might put the collection view into a NIB all its own. You'd create a subclass of NSViewController to load and own the NIB and set the class of the File's Owner placeholder in the NIB to that class. You'd connect the view outlet of File's Owner to the collection view and the delegate outlet of the collection view to File's Owner.

Related

What's the advantage of using UIViewController as owner of xib?

Most of the time, owners of xib is a UIViewController.
I sort of use it my self.
Still I am confused why.
I suppose, the viewDidLoad and viewWillAppear is kind of the main selling point.
Is that it?
What are the advantage of using UIViewController as owners of an XIB?
A UIViewController object is the main way for views to appear within an iOS window.
Apple provides this as a fundamental, foundational building block (along with so many others) which you can use to build upon quickly and get your app out to market.
And when you subclass UIViewController, you're able to do lots of beautiful customizations which can be collected and eventually turned into (hopefully decent) products. When you subclass a UIViewController, you need to set the "owner" of a XIB file to that subclassed view controller (e.g. ThioViewController), so that way the app knows what object (and user interface) is being instantiated.
Hopefully this isn't too super abstract of an explanation.
First, spend a bit time to understand MVC http://en.wikipedia.org/wiki/Model–view–controller
This is the milestone of Objective-C (not only) development.
UIViewController is controller for all your views (inside this viewController). It provide starting point for you to create views on the screen, manipulate the views, handle actions from views etc.
You can create UIViewController programmatically.
XIB is representation of the screen which you can comfortably operate in Interface Builder to create and customize design of your application screen or one of the screens.
Since XIB represent the screen(view) it must be the controller which controls all the view on the screen - UIViewController or UINavigationController or other type of controller depending of your needs.
Most of time you will subclass UIViewController and use it to achieve you goals.
UIViewController have several subclasses which inherit directly from it (UINavigationController, UITabBarController).
Also UIViewController hav several methods (some of them)
-(void)viewDidLoad
This method is called after the view controller has loaded its view hierarchy into memory. This method is called regardless of whether the view hierarchy was loaded from a nib file or created programmatically in the loadView method. You usually override this method to perform additional initialization on views that were loaded from nib files.
and
-(void)viewWillAppear:(BOOL)animated
Parameters
animated
If YES, the view is being added to the window using an animation.
Discussion
This method is called before the receiver’s view is about to be added to a view hierarchy and before any animations are configured for showing the view. You can override this method to perform custom tasks associated with displaying the view. For example, you might use this method to change the orientation or style of the status bar to coordinate with the orientation or style of the view being presented. If you override this method, you must call super at some point in your implementation.
Please check Apple documentation for more information
https://developer.apple.com/LIBRARY/IOS/documentation/UIKit/Reference/UIViewController_Class/Reference/Reference.html

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 does it mean to delegate to File Owner in my xib file?

I believe that UIView objects can delegate control to views in iOS programming. However, I thought this was already handled by an IBAction associated with an IBOutlet corresponding to the UIView.
In that case, what does it mean to drag a blue line (while pressing Ctrl) from the delegate circle of the UIView in my xib to File Owner?
Isn't the UIView already delegating to my view controller via an IBAction? The code seems to work if I don't specify anything for my UIView's delegate.
"Isn't the UIView already delegating to my view controller via an IBAction? The code seems to work if I don't specify anything for my UIView's delegate".
It looks like you're confusing the idea of the Target-Action Mechanism with delegation. While you could in a way think of target-action as involving “delegation”, it would only be in the most general sense of the word in that it’s the target (generally a controller) that handles and implements the action (the message). However, a Cocoa programmer would probably refrain from explaining the target-action mechanism by using that particular word – delegation – as it would be too easy to confuse it with actual Delegation.
When you “wire up” buttons and controls in the nib file to call IBAction methods in your controller object, that’s just the target-action mechanism at work. As you saw, the code works even if you "don't specify anything for my UIView delegate”, since target-action doesn’t involve delegation (in the Cocoa-sense of the word).
Delegation is generally used as an easier alternative to using subclassing to implement the desired behavior. For example, instead of having to create your own custom subclass of UITableView in order to have it know what data you want it to display, you can simply use the plain UITableView class, set its delegate to a controller class, and have the controller class implement the required/desired designated delegate methods. Using subclassing to accomplish that could potentially get complicated, since when you subclass, you need to have a full understanding of the inheritance chain and how all of the superclasses work.
File's Owner is just a fancy way of disguising the name of the class that the XIB is taking it's references from. When you drag the delegate outlet to your class, it's the equivalent of this line:
[self.myControl setDelegate:self];
When you drag while pressing CNTRL from an IBOutlet or IBAction to a UILabel, UIButton or something else, you are binding events or outlets to your controller.
A delegate sort of a controller that must implement specific functions depending on which type of delegate it is. For example, the UIViewController, which implements the UIViewDelegate protocol, can implement
-(void)viewDidLoad
the YourApplicationDelegate, which implements UIApplicationDelegate must implement
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
So a delegate is just a set of functions which define the behavior of an object, the classes that implement them can change this behavior.

Can I define an outlet in a .nib without specifying a controller?

I have a nib that has a button that I would like the relevant controller to have access to. But right now the owner is a generic NSViewController, and inside AppDelegate I assign the nib to the controller like:
[browseViewController initWithNibName:#"BrowseView" bundle:[NSBundle mainBundle]];
But is it possible within the nib file to assign a button's referencing outlet generically? In other words, to give the outlet a name and point it to File's Owner, and then if/when the nib is connected to the controller if that controller has an outlet with the same name it just works?
The File Owner has to have the certain outlet and/or the action when you connect it in IB. Even if you could connect it to an outlet that does not exist, an exception will be raised when the nib is being loaded. I you want to check it make an outlet, connect it to an object, save the nib, delete the outlet from the object and run the application. NSUnknownKeyException will be raised.
The easiest way would be to use a common superclass of your controller. If the controllers cannot be derived from the common ancestor, the only workaround I see is to make a protocol where you define your outlet properties and actions. Make an object that conforms to the protocol
MyObject: NSObject < MyNibProtocol >
now use this object in the nib to connect the outlets and actions.
However, the properties and methods cannot be optional, you have to implement them.

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.