Enable Unique Selection

  • I have a button which only makes sense when exactly one thing is selected.
    Currently it's Enabled property is bound to Array <Controller.selectedObjects....>.
    I.e. the button is enabled if one or more things are selected.

    But I want it to be disabled when nothing is selected AND also if more than one thing is selected.
    Is there a way to do this without code?

    If not - what to do ? Create a value transformer? Or what else?

    Gerriet.
  • On May 3, 2013, at 1:29 AM, Gerriet M. Denkmann <gerriet...> wrote:
    > I have a button which only makes sense when exactly one thing is selected.
    > Currently it's Enabled property is bound to Array <Controller.selectedObjects....>.
    > I.e. the button is enabled if one or more things are selected.
    >
    > But I want it to be disabled when nothing is selected AND also if more than one thing is selected.
    > Is there a way to do this without code?
    >
    > If not - what to do ? Create a value transformer? Or what else?

    I vaguely remember doing this by adding a readonly property to the array controller -- something like "exactlyOneIsSelected" -- with a corresponding getter method. Then you can bind to ArrayController.exactlyOneIsSelected.

    Then the question would be how to trigger KVO on that property. I don't remember what I did. My first thought would be to implement +(NSSet *)keyPathsForValuesAffectingExactlyOneIsSelected, but I'm not sure what to return. Maybe @"selectionIndexes"? Would @"<selectedObjects....>" work? I don't know if you can use aggregation in keyPaths...Affecting... methods.

    It might be useful to implement these methods on a category of NSArrayController if you need this logic in multiple places.

    As usual I have a nagging feeling there's a better way, but this at least should work.

    --Andy
  • On 3 May 2013, at 17:07, Andy Lee <aglee...> wrote:

    > On May 3, 2013, at 1:29 AM, Gerriet M. Denkmann <gerriet...> wrote:
    >> I have a button which only makes sense when exactly one thing is selected.
    >> Currently it's Enabled property is bound to Array <Controller.selectedObjects....>.
    >> I.e. the button is enabled if one or more things are selected.
    >>
    >> But I want it to be disabled when nothing is selected AND also if more than one thing is selected.
    >> Is there a way to do this without code?
    >>
    >> If not - what to do ? Create a value transformer? Or what else?
    >
    > I vaguely remember doing this by adding a readonly property to the array controller -- something like "exactlyOneIsSelected" -- with a corresponding getter method. Then you can bind to ArrayController.exactlyOneIsSelected.
    >
    > Then the question would be how to trigger KVO on that property. I don't remember what I did. My first thought would be to implement +(NSSet *)keyPathsForValuesAffectingExactlyOneIsSelected, but I'm not sure what to return. Maybe @"selectionIndexes"? Would @"<selectedObjects....>" work? I don't know if you can use aggregation in keyPaths...Affecting... methods.
    >
    > It might be useful to implement these methods on a category of NSArrayController if you need this logic in multiple places.
    >
    > As usual I have a nagging feeling there's a better way, but this at least should work.

    An interesting idea.

    I created a ValueTransformer like:

    @implementation UniqueTransformer

    + (Class)transformedValueClass { return [ NSNumber class ]; }

    - (id)transformedValue:(id)value
    {
    BOOL unique = [ value respondsToSelector: @selector(integerValue) ]  &&  [ value integerValue ] == 1;
    return @(unique);
    }

    @end

    Seems to me rather less code. Maybe still not the best way to do it, but the best I could think of.

    Kind regards,

    Gerriet.
  • Personally I would just use the value transformer approach. It's easy,
    obvious, and discoverable. Any other solution I can think up with
    would be lacking in at least one of these. I actually find value
    transformers to be super helpful when working with bindings. I've used
    one for an empty string (that trims newlines and whitespace before
    checking length), for an empty array, and probably some more.

    On Fri, May 3, 2013 at 11:54 PM, Gerriet M. Denkmann
    <gerriet...> wrote:
    >
    > On 3 May 2013, at 17:07, Andy Lee <aglee...> wrote:
    >
    >> On May 3, 2013, at 1:29 AM, Gerriet M. Denkmann <gerriet...> wrote:
    >>> I have a button which only makes sense when exactly one thing is selected.
    >>> Currently it's Enabled property is bound to Array <Controller.selectedObjects....>.
    >>> I.e. the button is enabled if one or more things are selected.
    >>>
    >>> But I want it to be disabled when nothing is selected AND also if more than one thing is selected.
    >>> Is there a way to do this without code?
    >>>
    >>> If not - what to do ? Create a value transformer? Or what else?
    >>
    >> I vaguely remember doing this by adding a readonly property to the array controller -- something like "exactlyOneIsSelected" -- with a corresponding getter method. Then you can bind to ArrayController.exactlyOneIsSelected.
    >>
    >> Then the question would be how to trigger KVO on that property. I don't remember what I did. My first thought would be to implement +(NSSet *)keyPathsForValuesAffectingExactlyOneIsSelected, but I'm not sure what to return. Maybe @"selectionIndexes"? Would @"<selectedObjects....>" work? I don't know if you can use aggregation in keyPaths...Affecting... methods.
    >>
    >> It might be useful to implement these methods on a category of NSArrayController if you need this logic in multiple places.
    >>
    >> As usual I have a nagging feeling there's a better way, but this at least should work.
    >
    > An interesting idea.
    >
    > I created a ValueTransformer like:
    >
    > @implementation UniqueTransformer
    >
    > + (Class)transformedValueClass { return [ NSNumber class ]; }
    >
    > - (id)transformedValue:(id)value
    > {
    > BOOL unique = [ value respondsToSelector: @selector(integerValue) ]  &&  [ value integerValue ] == 1;
    > return @(unique);
    > }
    >
    > @end
    >
    > Seems to me rather less code. Maybe still not the best way to do it, but the best I could think of.
    >
    >
    > Kind regards,
    >
    > Gerriet.
  • On May 4, 2013, at 12:54 AM, Gerriet M. Denkmann <gerriet...> wrote:
    > Seems to me rather less code.

    Well sure, if you want to write *less* code. :)

    (To add to the "duh" factor, I know I wrote other value transformers on that project.)

    --Andy
previous month may 2013 next month
MTWTFSS
    1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31    
Go to today