NSViewController and bindings - objective-c

In my application I have a single nib file. The File's Owner is a NSViewController and insider there is just a vertical slider that I want to bind to a property in one of my classes. (I don't have any other nib files since it is a status bar application, so I don't have a window). The nib is loaded runtime to create a custom view for a NSMenuItem.
The problem is that I want to use an object controller to do the binding but I'm not sure what is the content of the object controller. How can I access from the nib to an arbitrary class in my project?
In the examples I have seen, usually the object controller uses the File's Owner to access the class (and the property for the binding) setting the Content Object binding to the File's Owner. But in my case from the File's Owner I do not have access to the class.
Any pointer?

Ok this works for me. It is enough subclassing NSViewController and sets the new subclass as the File's Owner. Now it is possible to use a Controller Object to bind through the File's Owner.

If you use XCode 4 you can Control-drag from the slider to the .h file (AppController.h?), and you will get the option to generate an outlet or an action. If you want to create an action, caused by sliding the slider, you should select action. The generated method will be called whenever the slider is changed. If you want the slider value to react to an event (or a changed instance variable in your program), set it to 'outlet'.
Hope that helps, let me know if you were really looking for something else :-)

Related

Xcode 6.1 cannot drag connection to a property from XIB

I've just started with Xcode and I'm having a certain difficulty. I've placed a label on the canvas, declared property in viewcontroller.m, and now I'm trying to draw a connection into it, but it doesn't seem to exist. What am I doing wrong ?
I've added a screenshot - the property is not on the list for some reason, as you can see.
Using Xcode 6.1!
http://i.imgur.com/xYfoCnh.png
Select your view in your xib file and then click on File's Owner here:
With File's Owner selected, then open the identity inspector and make sure the class of File's Owner is ViewController like so:
Once you set the class of File's Owner to ViewController, you should see the UILabel property appear in the Connections Inspector for File's Owner.
Also, just for reference, the File's Owner for a view in a Xib file typically refers to the view controller (the view controller owns its view).

iOS: UIView directly implementing a Nib

Sorry if this has an obvious answer, I can't seem to find anything describing this situation. How can I set up a nib file which directly implements a custom UIView? In other words, the top-level view in the nib file becomes an instance of my custom UIView class? The closest I've been able to find so far is to create a custom UIView which loads the nib and sets it's top-level view to a UIView* property (and all it's subviews to the appropriate outlets by loading with owner:self). This works, but as I understand the top-level View does nothing except act as a container for all the other views - which is what my custom UIView is supposed to do. Any suggestions?
Edit: I got this in the end: the issue is my custom view class was set as the File's Owner class, when it should have been set as the top-level View's class. I didn't know it was possible to set outlets on elements in the IB as well as the Owner. Setting the Owner to the class of the ViewController that will hold it and the top-level view to my custom view has it all working.
If you create a project using the single view template, you will get an empty view. If you add a class that is a subclass of UIView, you can change the class of that view in IB to your class (in the identity inspector).
If I have understood your question correctly, then this should help -
In the IB, on the right-pane. select the "custom class" dropdown & fill in your custom UIView class. The image shows UITableViewCell instead of that put your custom UIView class name.
Correct me if I have not understood your question correctly.

What's meant by File's Owner exactly?

What is meant by "File's Owner"? The XIB interface says it's UIApplication, but why is it named so? Which file does it own? I understand MVC to some extent, but I never heard of "File's Owner". What does it have to do with the controller of the application?
File's Owner is a proxy for the object that's specified as the owner when the .xib is loaded. Usually, it's the object that's actually loading the .xib. In any case, it's important to realize that File's Owner represents some object that's external to the objects in the .xib file, and as such it's basically the way that objects inside the .xib are connected to something outside the .xib and vice versa.
This all has very little to do with MVC and a lot to do with how Interface Builder works. Typically, you add IBOutlet properties and IBAction methods to the object that will load a .xib (such as an application delegate or a view controller). Then, using IB, you connect objects inside the .xib to the File's Owner proxy, and you set File's Owner as the target of your controls (choosing the appropriate action for the control).

How do I set a property on a custom view instantiated from a XIB

I am just trying to get my head around MVC in Objective C and IOS but am having a problem I'm hoping someone can help me with.
I have created a custom view (created as a child UIView in a XIB) that uses a simple delegate protocol for requesting information from its delegate in drawRect. I have a view Controller that implementes the protocol and is connected to the view through interface builder.
The custom view also has a few properties that I want to set on startup.
The problem I have is working out how the controller is supposed to access the view to set these properties as it doesn't appear to have direct access to it. Also the properties don't seem to be visible in interface builder inspector as I would expect unlike the delegate property I added.
Initially I thought I could do something like
[self.view setViewIntProperty:10]
But that would be calling the main XIB view and my custom view is actually a child of this view so I need someway to get that specific child view to I can initialise it from the controller in viewDidLoad.
Hopefully that is clear. I'm sure this should be easy and I've missed something simple but can't see how this should normally work.
You can just create another property on your view controller of type MyCustomView*.
Declare that property as an IBOutlet and you wire that up in IB.
Then in your view controller you can use that property to access that custom view.
Your custom view's properties (as opposed to its outlets) can only be set in code unless you create an IB plugin for it.
Your other subviews can be accessed easily if you create an outlet for each of them in your controller. The view outlet is there as the primary view of that view controller. There is nothing preventing you creating additional outlets to other views/controls. Yu would just need to subclass the view controller and add the outlets as needed. Just remember to set the class name of the controller (in Interface Builder) to that of your custom subclass. That will expose the available outlets for you to connect.
You'd still need to create an Interface Builder plugin if you want to make your control's custom properties available in IB's inspector palette. Unless you plan to reuse it frequently in other applications or make it available to others, it's probably easiest just to set the properties in your source code.
Example for setting corner radius of your custom subview (subclass of UIButton in my case) from xib.
Create a property like this
#property (nonatomic, assign) IBInspectable CGFloat cornerRadius;
Override setter in your custom view's implementation file.
-(void)setCornerRadius:(CGFloat)cornerRadius
{
self.layer.cornerRadius = cornerRadius;
}
Drag your view in xib and change its class to your custom class.
Magic... You will see the custom properties appearing in attribute inspector like this.

Core Data bindings with subviews and multiple NIBs

I have a document-based Core Data app. My main Core Data entity has several string fields, most of which are bound to NSTextFields, but one is bound to an NSTextView.
I am using the technique for view switching (with multiple view controllers) as explained in the Hillegass book. All of my subviews are controlled by a ManagedViewController, my subclass of NSViewController that has a managedObjectContext field.
My subview exists in a separate nib file. For some reason, the bindings I have set up in that nib are not working--but if I set up the widgets and the bindings in the exact same way in the main nib file instead, they work fine.
See image:
Screenshot http://img180.imageshack.us/img180/3391/screenshot.gif
In the main nib file, I have a tree controller whose managedObjectContext is bound to File's Owner's mOC (File's Owner is MyDocument). The NSTextField's value (yes, value--it's not rich text) is bound to treeController.selection.content (where content is a string property of the entity.) No problem. This works fine.
In the second nib file, I have another tree controller whose managedObjectContext is bound to File's Owner's mOC (File's Owner is my ManagedViewController). The NSTextField's value is bound the same way as above.
In my code, I have tested to make sure that the two managedObjectContexts refer to the same object. They do, and it's not nil.
I don't get an error--it's just that the values never bind with NSTextViews in the subview. They're always nil.
Also, I have tried NSTextFields--same problem.
Any ideas on how to make Core Data bindings play nicely with subviews and multiple NIBs?
You have two tree controllers. Each has its own knowledge of the selection. Try binding selectionIndexPaths from both of the tree controllers to a property of your document (you'll need to provide a way to get there through the view controller).