Re: NSSlider and arrangedObjects
Re: NSSlider and arrangedObjects
- Subject: Re: NSSlider and arrangedObjects
- From: Tobias Wood <email@hidden>
- Date: Sat, 21 Jan 2012 10:05:30 +0000
Thanks for the responses guys, I think I follow most of it.
My documents for this app are essentially movies (4D images, the 4th dimension is time). I want this particular slider to set the timepoint for all open documents, in a 'write only' fashion. Currently there is no UI to set the timepoints individually, and each document carries internal logic to prevent setting a timepoint beyond the end of the file.
Currently I have implemented this behaviour by binding the slider to a property on my document controller, and the setter for this forwards the desired timepoint onto all open documents. I was hoping to replace this with a binding just to eliminate some glue code.
I thought it would be simple because I have another slider which is bound to the 'contrast' property of the selection from the array controller, and this behaves exactly as I want it to (the selection is controlled via a table view, and the slider will set the contrast of all selected rows).
I hope the above is clear. Is keeping the property on the document controller likely the simplest way forward?
Toby
On 21 Jan 2012, at 08:54, Ken Thomases <email@hidden> wrote:
> On Jan 21, 2012, at 1:00 AM, Quincey Morris wrote:
>
>> On Jan 19, 2012, at 03:03 , Tobias Wood wrote:
>>
>>> Binding the NSSlider's value to the NSArrayController's "arrangedObjects.propertyName" causes my program to get a SIGABRT on opening, with the following uncaught exception:
>>> "Cannot create double from object ( ) of class __NSArray0"
>>>
>>> I assume this is to do with the empty array.
>>
>> No, it's because you can't bind through a key path that contains a collection property ("arrangedObjects" in this case).
>
> Not to get too deep into the weeds, but arrangedObjects is, like selection, also a proxy and it does allow binding through it. That's a big part of its purpose/value.
>
>> This situation is complicated by the fact that NSArray responds to a selector it doesn't recognize (such as your "propertyName") by returning the result of sending this selector to every element in the array.
>
> Um, not quite. This isn't about not responding to a selector, it's about its implementation of -valueForKey:. NSArray implements -valueForKey: by returning an array of the results of invoking -valueForKey: with the same key argument on each of its elements.
>
>> This array result isn't convertible to the slider's numeric value by any standard KVC mechanism, so you get the exception.
>
> That's the meat of the issue.
>
>
>>> I have tried binding the NSSlider's enable to "arrangedObjects.@count" and "arrangedObjects.canRemove". Neither fixes the problem. If I bind the value to "selection.propertyName", the enabling/disabling works as expected (i.e. the slider is greyed out until the array has at least one entry). Hence I am confused.
>>
>> There's an important difference between "selection" and "arrangedObjects". The latter is an array, but "selection" is a proxy object that represents either a single object from the controller (*the* selected object), or a special multiple-selection marker, or a special invalid value marker, or a special no-value marker. The special markers are used (for example) for making text fields show "multiple selection" or "no value" messages, and for automatically enabling/disabling controls as you noted.
>
> You correctly diagnosed that the exception was due to the inability to make a double from the array. That's the whole of the necessary explanation for the symptom. Tobias had simply made an incorrect assumption that it was due to the array being empty, but neither that nor the no-selection marker from the selection property are relevant.
>
> It is true that the automatic enabling/disabling when bound to selection.propertyName is due to the selection's markers and the Conditionally Sets Enabled bindings option (which is on by default). But that doesn't resolve the confusion about why it was throwing an exception in some cases and not others.
>
>
>> Again, there's a complication. Table view *column* bindings are special in that they appear to be able to bind through collection objects, but in fact their key paths are treated as 2 separate parts by the bindings mechanism. The first part allows the column to find the array of values for all table rows, and to choose the correct value per row based on the row index; the second part allows the column to find the actual value to display.
>
> Table columns do have special handling for array-valued bindings. It's that they distribute the array values among their rows. Table columns are not special in being able to bind through collection properties. That's a feature of NSArrayController.
>
> The table column's bindings still have just an observed object (often the array controller) and a single key path (often of the form "arrangedObject.propertyName"). It's just that, when they receive an array from [observedObject valueForKeyPath:observedKeyPath], they know to pick one element from that array for each row.
>
>
>> It's not entirely clear what you mean. Are you saying you want to have a single slider in your window, that somehow represents all the array elements? If so, what value would the slider show when the array elements have different values for the relevant property? Is there a table view involved in this somewhere?
>
> Yes, these are the important questions. Tobias, what do you actually intend the slider to signify? What should happen when its value is adjusted by the user?
>
> Regards,
> Ken
>
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden