Giving a Boolean property to a controller object in Interface Builder - cocoa

After I drag a controller object to the document window, how do I give it a Boolean property?

Assuming you want the ability to expose and edit the property values of your custom controller as attributes showing up in IB's inspector, you'll need to write your own plugin which tells IB what the inspector should look like. This really can't be answered briefly.
Here's Apple's reference on IB Plugins:
http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/IBPlugInGuide/Introduction/Introduction.html#//apple_ref/doc/uid/TP40004323-CH1-SW1
And here's the inspector portion:
http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/IBPlugInGuide/CreatingInspectors/CreatingInspectors.html#//apple_ref/doc/uid/TP40004323-CH6-SW1
If you truly just want to add a property to the controller's interface, you do this in Xcode (modifying the interface and implementation accordingly) and IB will pick up the changes automagically.

In the case of a checkbox, the checkbox itself is either checked or not. That state stores the boolean value instead of the controller (unless you wish it.)
To have the app undertake an action upon clicking it, think of it as a button instead of a data display and link it to an action method in the view controller. That's the simplest and old school way of doing it.
To use binding, you need to bind the checkbox's value attribute to a controller. Usually for binary values its an object controller. So, in IB, drag an Object controller to your nib window and bind it to your data source. Then, drag a checkmark button to the interface. In the checkmarks binding inspector. Set "value" binding to the name of the object controller, controller key to selection, keypath to the name of the data source attribute and provide a value transformer if needed.

Related

Best practice for setting a data source and delegate for a UITableView

This question may not have a straight answer, but I am curious as to what others think. I have a UIViewController and inside that I have 2 objects a UIView and and UITableView. Each object as it's own custom class. My question is about the UITableView, what object should be the datasource and the delegate. Right now I have the UIViewController set to those rolls, but is it beset practice to set the object itself to be the data source and the delegate, maybe use the method awakeFromNib to set those 2 sources. Are both ways ok? I would think that setting the data and the delegate to the class that represents the tableview would keep that code apart from the view controller, which I would think would be a good thing.. but maybe not...
Good question actually.
Look at the Controller as an example of the Mediator Pattern from the Gang of Four: it's mediating the relationship between the View and the Model. Most of the web world has gone to using binding of some sort, so you typically see model objects 'bound' directly to the view layer, e.g. a text edit field might have an expression indicating which field in the domain object it is editing, then the framework will provide the services of marshaling and unmarshaling that data.
In Cocoa, you typically don't do that: you bind to properties in the Controller, and those typically are then used to transform the underlying domain class. So for instance, if you make a storyboard and make a form and have a custom controller, now you want to edit the name of some entity, e.g. User, you would CTRL-drag from the edit box over to the source, it would make an outlet, which would then give you control not only of what appears in that box, but the control itself. Then you could add a submit button and CTRL-drag to create a method, for Save, and when that's clicked, you could update the underlying User instance.

Binding a Menu Item to a property of the First Responder

I have a document-based application.
In my document class,
I have a BOOL property : isActionPossible.
I also have an IBAction : - (IBAction) doTheAction:(id)sender.
Now, in MainMenu.xib, I want to connect a menu item to the action.
This is easy, when you know that the First Responder in Interface Builder "stands for" the active document of your application.
But how shall I do to bind the availability (the "enable property") of this item menu with the BOOL property isActionPossible of the active document ?
Indeed, in the list proposed, there isn't "First Responder".
Two choices:
You can implement menu validation, see Apple's docs. In short before a menu is displayed the system sends a validation request to the same object that handles the action, which includes the first responder. You simply add a method to your document class which returns a BOOL; in your case your isActionPossible property.
Use the currentDocument property of NSDocumentController which returns the document associated with the main window. You can then use bindings to bind <Document Controller>.currentDocument.isActionPossible. This approach is more general as you can bind label contents to values etc. as well as use it for menu bindings.

How to set the action of a NSButton in a binding scenario?

I have a button that is inside a view repeated inside a NSCollectionView. I can bind the title of the button to one of the properties in my model class but I want to wire the selector of the button to one of the selectors in my model class. Obviously, the button must send the message to the model object associated with the corresponding collection view item.
I managed to bind the target for the button but how to set the selector? I want to do that in Interface Builder if possible...
I figured it out. In the Ib there is a selector textbox bellow the path textbox where I bind the target. I don't know why I didn't see it. I spent nearly one hour trying to solve this issue.
How to add those blindings? I still can't find it.
I find it . It's Here.

How to bind objects in NSDictionary in NSUserDefaults?

How do I bind NSDictionary objects to several text fields in Interface Builder?
I would like to bind each object to a specific item in the dictionary. For example, the first text field should be bound to Actor:
You need to add a NSObjectController in Interface Builder. In the attributes inspector tab leave the standard mode "Class" and class name on "NSMutableDictionary", but switch "Prepares Content" on. In the bindings inspector bind "Content Object" to "Shared User Defaults Controller", controller key "values" and "Model Key Path" to your dictionary's key in User Defaults. Switch "Handles Content As Compound Value" on.
Now you can bind your text field (or check boxes etc). values to the ObjectController, with controller key "selection" (!) and the keys in your dictionary (as model key path).
Hope this helps. I couldn't find the answer in Apple's documentation and also not in the net, was lucky to find it out myself by trying different controller objects...
First: #keeluu's answer should be marked correct.
Doing it Programmatically
If you're doing this in code rather than through IB, there's a "gotcha" to look out for. It looks like this:
// Assume 'anObjectController' is an NSObjectController.
// Assume 'userDefaultsController' is [NSUserDefaultsController sharedUserDefaultsController]
// Assume 'someDictionary' is an NSDictionary in userDefaults.
[self.anObjectController
bind:NSContentBinding
toObject:userDefaultsController
withKeyPath:#"values.someDictionary"
options:#{NSHandlesContentAsCompoundValueBindingOption: #YES}];
If you do the above, you'll find that when you bind your UI elements to properties in someDictionary, those UI elements will correctly display the values that are IN user defaults, but when you change them (by say, clicking a bound checkbox) those values will NOT be updated in user defaults; the old values stick around.
The Reason
The binding must be to NSContentObjectBinding instead of NSContentBinding. The NSObjectController class exposes a binding named contentObject. When you bind to that, everything works properly.
This is an easy mistake to make because Xcode's code completion automatically goes for NSContentBinding and it's one of the most frequently used binding names anyway. This just cost me hours of trouble, so hopefully I saved someone else some time.
Try to add NSDictionaryController to you .xib file, then bind its Controller Content to your dictionary in User Defaults. Then you can bind text field values to Dictionary Controller (arrangedObjects key).
I never tried that but I think it must work.
Hope, it helps.

Basic Cocoa Bindings: Toggle a boolean from menu in IB

I'm just getting started with Cocoa Bindings and while I've read through much of the documentation, I'm still struggling to implement a basic feature, making me question wether I'm doing it wrong or perhaps it's just not possible via IB.
Goal: Have a menu item called "Toggle visibility" toggle the state of a Boolean property in my application controller (AppController) called "visibility." I think this should be possible completely through IB.
(Note: CoreData is not in use here)
What I think needs to happen is I need to have an NSObjectController who's content outlet is set to my AppController class. Then I think I need to use an Action Innvocation binding. But here's where I run into trouble.
Should the Controller Key be selection? Should the Model Key Path be the name of my Boolean Property? What should Selector Name be?
Or do I need to setup a separate action method called "toggleVisibility" that I can bind to? If I did, why wouldn't I just use standard target/action associations, rather than bindings?
Any input / direction appreciated.
Goal: Have a menu item called "Toggle visibility" toggle the state of a Boolean property in my application controller (AppController) called "visibility."
Your goal tells you why you are failing.
In your description of your goal, you say that you want to set this menu item up as a command, a verb, an imperative sentence—“toggle the visibility”. But that's not the right title for the menu item.
Moreover, implementing a verb menu item with Bindings is inherently difficult because Bindings is the wrong tool for the job. Bindings is for exposing properties in your UI. It isn't for performing commands.
The correct title is supported by the correct Bindings-based solution.
The correct title of the menu item is, simply, “Visible”.
This alone should give you a hint as to how to proceed. Here's another: When the selection is visible, the menu item should have a check mark; when it is not visible, the menu item should have no mark.
You want to bind a property of the menu item to, ultimately, a Boolean property of your controller. Normally, this property of the menu item would be state, but for whatever reason, the binding for it is named value.
So, bind the value binding of the menu item to the Boolean property of your controller.

Resources