another responder chain docs bug (validateUserInterfaceItem:)

  • Semi-related to my previous post, I just filed rdar://7577360 (text below).  As far as I can tell, it's a bug in the docs.

    --Andy

    The "Overview" at <http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Applic
    ationKit/Protocols/NSUserInterfaceValidations_Protocol/Reference/Reference.
    html
    > says: "To validate a control, the application calls validateUserInterfaceItem: for each item in the responder chain, starting with the first responder. If no responder returns YES, the item is disabled."

    > From my experience, this is not what happens.  Rather, it works the way Jakob Olesen describes in this post on cocoa-dev:

    <http://www.cocoabuilder.com/archive/cocoa/168662-validateuserinterfaceitem-
    and-chaining-actions.html
    >
    "1. Find the target for my action
    2. Validate using that target and nobody else."

    I.e., validateUserInterfaceItem: does not go up the responder chain until it gets a YES answer; it goes up the responder chain until it finds a target that responds to the action message, meaning the docs are incorrect.
  • Am 26.01.2010 um 00:31 schrieb Andy Lee:

    > Semi-related to my previous post, I just filed rdar://7577360 (text
    > below).  As far as I can tell, it's a bug in the docs.
    >
    > --Andy
    >
    >
    > The "Overview" at <http://developer.apple.com/mac/library/documentation/Cocoa/Reference/Applic
    ationKit/Protocols/NSUserInterfaceValidations_Protocol/Reference/Reference.
    html
    > > says: "To validate a control, the application calls
    > validateUserInterfaceItem: for each item in the responder chain,
    > starting with the first responder. If no responder returns YES, the
    > item is disabled."
    >
    >> From my experience, this is not what happens.  Rather, it works the
    >> way Jakob Olesen describes in this post on cocoa-dev:
    >
    > <http://www.cocoabuilder.com/archive/cocoa/168662-validateuserinterfaceitem-
    and-chaining-actions.html
    > >
    > "1. Find the target for my action
    > 2. Validate using that target and nobody else."
    >
    > I.e., validateUserInterfaceItem: does not go up the responder chain
    > until it gets a YES answer; it goes up the responder chain until it
    > finds a target that responds to the action message, meaning the docs
    > are incorrect.

    Well, in my experience the truth is somewhere between the two:

    AppKit seems to go up the responder chain and call
    validateUserInterfaceItem: on each potential target (i.e. each
    responder that responds to the action message and responds to
    validateUserInterfaceItem:) until the first call to
    validateUserInterfaceItem: returns YES.
    If none of the potential targets returns YES from
    validateUserInterfaceItem:, the item is disabled.

    </jum>
  • On Wed, Feb 3, 2010 at 1:02 AM, Jens Miltner <jum...> wrote:
    > Well, in my experience the truth is somewhere between the two:
    >
    > AppKit seems to go up the responder chain and call
    > validateUserInterfaceItem: on each potential target (i.e. each responder
    > that responds to the action message and responds to
    > validateUserInterfaceItem:) until the first call to
    > validateUserInterfaceItem: returns YES.
    > If none of the potential targets returns YES from
    > validateUserInterfaceItem:, the item is disabled.

    Correct.

    If a control's target is non-nil, and that target doesn't respond to
    the action selector, the control is disabled. If it does respond to
    the action selector, and doesn't do UI validation, the control is
    enabled. Otherwise, the control is either enabled or disabled
    according to the result of calling the UI validation method.

    If a control's target is nil (aka First Responder), AppKit walks the
    responder chain until it finds a control that responds to the action
    selector. If it can't find one, the control is enabled. If it does
    find one, logic proceeds as above.

    While this has served well for the past 20 years, we find it's not
    optimal. We'd like AppKit to continue searching, rather than abort, if
    it finds a control that responds to the action selector but doesn't
    validate, and we would like targets to be able to add pieces to the
    responder chain dynamically (very useful for control delegates).

    So Tim wrote OATargetSelection. It lives in our open-sourced
    OmniAppKit framework—specifically in -[OAAplication
    sendAction:to:from:] and supporting methods. You can find it here:
    http://github.com/omnigroup/OmniGroup/blob/master/Frameworks/OmniAppKit/OAA
    pplication.m


    --Kyle Sluder
  • On Feb 3, 2010, at 11:42 AM, Kyle Sluder wrote:
    > On Wed, Feb 3, 2010 at 1:02 AM, Jens Miltner <jum...> wrote:
    >> Well, in my experience the truth is somewhere between the two:
    >>
    >> AppKit seems to go up the responder chain and call
    >> validateUserInterfaceItem: on each potential target (i.e. each responder
    >> that responds to the action message and responds to
    >> validateUserInterfaceItem:) until the first call to
    >> validateUserInterfaceItem: returns YES.
    >> If none of the potential targets returns YES from
    >> validateUserInterfaceItem:, the item is disabled.
    >
    > Correct.
    >
    > If a control's target is non-nil, and that target doesn't respond to
    > the action selector, the control is disabled. If it does respond to
    > the action selector, and doesn't do UI validation, the control is
    > enabled. Otherwise, the control is either enabled or disabled
    > according to the result of calling the UI validation method.
    >
    > If a control's target is nil (aka First Responder), AppKit walks the
    > responder chain until it finds a control that responds to the action
    > selector. If it can't find one, the control is enabled. If it does
    > find one, logic proceeds as above.

    This is my understanding, but it is not quite what Jens wrote.  The difference is in when the traversal of the responder chain stops.  As you say, it stops with the first object that responds to the action selector, *regardless* of whether that object does UI validation, and *regardless* of what UI validation (if implemented) returns.

    > While this has served well for the past 20 years, we find it's not
    > optimal. We'd like AppKit to continue searching, rather than abort, if
    > it finds a control that responds to the action selector but doesn't
    > validate, and we would like targets to be able to add pieces to the
    > responder chain dynamically (very useful for control delegates).
    >
    > So Tim wrote OATargetSelection. It lives in our open-sourced
    > OmniAppKit framework—specifically in -[OAAplication
    > sendAction:to:from:] and supporting methods. You can find it here:
    > http://github.com/omnigroup/OmniGroup/blob/master/Frameworks/OmniAppKit/OAA
    pplication.m


    Thanks!

    --Andy
  • Ack, I need to correct myself.

    On Wed, Feb 3, 2010 at 8:42 AM, Kyle Sluder <kyle.sluder...> wrote:
    > selector. If it can't find one, the control is enabled. If it does

    I meant to say that if AppKit can't find a control in the responder
    chain that responds to the action selector, the control is *disabled.*

    --Kyle Sluder
previous month january 2010 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