initializing a cocoa IB binding - xcode

I have an NSTextField and an NSStepper that I'm trying to bind together. The stepper is setup to go from 0 to 100, and I'd like an initial value of 30.
For the stepper bindings, I have:
value: bind to Object Controller, controller key = selection, model key path = edgeThreshold
For the stepper attributes, I have
min=0, max=100, increment=1, current=30
I've got the text field set up in a similar fashion
bindings, value: bind to Object Controller, controller key = selection, model key path = edgeThreshold
When I run the program, everything works as I'd expect. If I hit the stepper up, the text field increments. If I type in a new value, and then hit the stepper, the value adjusts from my typed in value.
The problem is that the initial value in the text field is nothing (empty), and the initial value of the state appears to be 0. If I hit the stepper after launch, the text field changes from nothing to 1. So I can't figure out where to put the 30, and where the state of this binding really lives. I thought it might be in the object controller, so I set its dictionary to have a keypath and value of "selection.edgeThreshold" and 30...but this did nothing as well.

You don't really need the object controller. You can just bind the values of both the text field and the stepper to the property, edgeThreshold. So, if that property was declared in the app delegate, they would be bound to App Delegate.edgethreshold. If you then set that property to 30 in your applicationWillFinishLaunching method (self.edgethreshold = 30;), the text field will show 30 when the app starts up and the stepper will be set to 30 as well (it doesn't matter what you set the starting value to be in IB, this will override it).

I found a youtube video which pretty much does exactly what I was trying to do:
http://www.youtube.com/watch?v=ESk6YLDtGR8
Rather than instantiate an Object Controller to handle the bindings, I gave my app controller a few properties, and then bound to it. In the app controller's -init method, I set my desired startup values.

Related

Viewholder's views association

I have a RecyclerView whose viewholder contains a button and a textview(Which contains the numberical value starting from 0). I want whenever that button is pressed, the value of the textview gets incremented. I tried using setTag() in onBindView but of no use. The value of the textview gets incremented in one or more viewholders with that approach.
Please help!!
Somehow I managed to achieve the same myself. It is simple as there is no need for setTag() method anymore. Just take a map which stores the key(getAdpaterPosition()) and the value of the textView. When the button is pressed, increment the value of the textview in the map corresponding to the key(position). In the onBindViewHolder(), take the position argument and get value for the corresponding position from the map and set it in the textview. If the key exists in the map, get the value else get default value(0 in my case). In case, one doesnt understand let me know I will submit code here as well.Thanks.

How to connect NSPopUpButton with measurement unit choices to the way a NSTextField is presented?

In a Core Data entity i have a ā€˛length" attribute. I save the length in centimeters.
I want to give the user the possibility to view and edit the length in centimeters or inches. So i place a NSTextField next to a NSPopUpButton with cm and inch as choices.
What is the best way to format the NSTextField according to the choice taken by the NSPopUpButton? If reasonable for this problem i would want to work with bindings as much as possible.
I saw there are
NSNumberFormatters and
NSValueTransformers
or i could write custom code to transform the units?
What is the most elegant way to solve this problem?
If you persist the cm/in choice for the user as a per-entity choice with an attribute on the entity, you could do it with a value binding and a custom value transformer with reverse transformation on the textfield, a cm/in choice binding on the popup, and a keyPathsForValuesAffectingLength class method on the entity.
If the attribute displaysInInches-- or whatever you call it-- is registered as a keyPath that affects length's value, the custom value transformer would get called when the popup is toggled, and the text field would update.
If the cm/in choice is from user defaults (if the change is not per-instance), you could bind the popup to user defaults and have the custom value transformer take the default into consideration, but changing that popup wouldn't refresh the textfield. So I think you'd need an IBAction just to touch the instance's length.
You could add a number formatter on top of that-- especially if your value transformer transforms into NSNumber and not NSString-- but mostly for localization and number of significant digits, not for the cm/in math.

values passing from one window to other in cocoa application

im new in cocoa ..
can any one say how yo pass values fromm one window to other
i tried but windowController
not allowing to create instance of other class
For passing one value to other Window ??
Window is just a view, you pass model's value, not view's values.
So, whenever you need to pass the value, you can use
Notification
Delegate
Shared Class.

Cocoa: How to bind a boolean property to NSCellStateValue?

I would like to bind the boolean enabled property of an NSTextField to the state of an NSButton. I already tried adding a custom NSValueTransformer that transforms the state of the NSButton into NSNumber. However, in that scenario the text fields are disabled all the time for some reason. My second approach: To bad fails also since NSValueTransformer does not offer return primitives types such as BOOL.
Example:
The screenshot shows an example in which the text fields are disabled because the checkbox has the state NSOnState. I also would like to bind the labels to this state.
Further, it would be convenient, if I could set a "disabled text" in Interface Builder. In the above example I set the text in the associated class.
Edit:
I set self.anonymousLoginCheckbox.state as the Model Key Path for the enabled property of the account text field. Similar for the password text field. However, it does not work.
Update:
I created an example project available on GitHub showing the implementation kindly described by Nicolas Bachschmidt.
NSButton isn't KVO compliant for the key state. Cocoa Bindings require the observed object to emit notifications when the observed property changes. As NSButton's state is just a wrapper for its cell's state, -[NSButton setState:] method (and the automatic KVO notifications) isn't invoked when the user click the button (but -[NSCell setState:] is). If you set the model key path to self.anonymousLoginCheckbox.cell.state, it will work.

Best Practice for Manipulating UI Elements In Cocoa

I'll start by saying that I'm new to cocoa development. I'm also surprised I didn't find a post about this already, but I've filtered through a number of posts now without success.
I have a set of elements that should change state based on the state of a long running algorithm.
Basically, I have a start button, a cancel button, and a next button. The initial state of the app would be start button enabled, cancel and next buttons disabled. The status of the algorithm should swap enabled / disabled on all the buttons as it progresses.
Every option for manipulating button state I have seen involves coding button.enabled into the controller code. I'm coming from an ASP .NET MVC background as I dive into Cocoa and this seems backwards to me. Shouldn't the view logic be separated from the controller logic in the MVC pattern?
To me, it seems I should be able to emit a couple boolean values as IBOutlets like algorithm running and algorithm success, and bind the button state at the view layer. Do I need to toss this idea? Or am I possibly missing something about the Cocoa version of design pattern (like the object I bind the view to should really be a view model, which interacts with a controller class)? Or, lastly, is there an easy way to accomplish what I'm talking about, and I've just missed it.
You don't need to code the enabled state of the button into your controller. What you can do is declare a BOOL property on your controller such as isBusy and then set this property to YES when you start your long operation and to NO when it's finished. You must do this using Key-Value Coding-compliant methods, which essentially means using the setter, so you'd call self.isBusy = YES;, for instance.
The reason you do this is because you can then use Cocoa Bindings to set up a binding on the UI controls. Go into the bindings inspector for one of your buttons, and bind the Enabled binding to your controller object with a key path of isBusy.
Cocoa bindings uses Key-Value Observing (KVO) to monitor the value of observed properties. When a change occurs in the isBusy property, the buttons that are bound to it will notice and change their enabled state in response.
You might be missing the delegate model of Objective-C. In the example you are giving you could have your controller object running the algorithm and updating its status to its delegate, in this case the view.
i.e your ViewController object will call the doSomething method from the ProgramController; and when its over ProgramController will invoque the somethingDidFinish method from its delegate, as defined in your ProgramControllerDelegate protocol)

Resources