Re: Calling commitEditing text field loses focus

Christiaan Hofman <[email protected]> Wed, 21 Dec 2011 17:28:09 +0100
Newsgroups gmane.comp.macosx.devel
Message-ID <[email protected]>
On Dec 21, 2011, at 17:08, Jim Correia wrote:

>=20
> On Dec 21, 2011, at 3:15 AM, Christiaan Hofman wrote:
>=20
>>> This is how it has worked since NSController was introduced.
>>=20
>> I am pretty sure that long ago when I tested these things out it did =
remain first responder. I distinctly remember being frustrated that it's =
so hard to manually (i.e. without bindings) commit without losing first =
responder the way bindings can do.
>=20
> I=92ve been using bindings since 10.4, and this is always how =
-commitEditing has worked. (I wouldn=92t have gone through the trouble =
to write -commitEditingAndRestoreFirstResponderMumbleMumble otherwise.)
>=20
>>> It is less than ideal for a number of reasons. (You need to commit =
editing before saving, but that really shouldn=92t change keyboard =
focus, nor should it change the user=92s selection in many situations.)
>>>=20
>>=20
>> Sorry, can't think of any. If it can push through an edit on every =
key stroke without losing focus, why can't it do that at a point when I =
ask it to?
>=20
> Depending on the user interface element, it may also be appropriate to =
end editing on save, and select the entire context of the field, for =
example. (This isn=92t giving up first responder, but it isn=92t =
preserving the insertion point either.)
>=20
>>> If you want to solve this problem specifically, you can manually =
push the value through to the bound object when the field is editing. =
(Make sure you also take care of the value transformer case. Yes, this =
feels a little bit like you=92ve given up most of the advantages of =
having bindings.)
>>=20
>> Not just a little. That basically makes bindings meaningless, it =
comes to manual updating the old way with an extra registration layer =
added.
>=20
> It=92s good for dramatic effect, but calling bindings useless because =
it gets this aspect wrong is kind of harsh.=20
>=20

I am saying that if you implement manual updating on top of binding you =
can just as well forget about binding because it does not add anything =
anymore. In this situation. I am not saying that binding would not have =
other uses still.

>>> A more general solution would be to write something like adding
>>>=20
>>> 	- (void)commitEditingAndRestoreFirstResponderMumbleMumble;
>>>=20
>>> to NSController. It=92s a bit tedious to get this implementation =
right, since you have to handle NSTextView, plus field editors for the =
various types of things which might use them, scrolling selection ranges =
back into view, etc. This will take longer, but then you=92ll have the =
problem solved centrally,  once and for all.=20
>>=20
>> Well, and not to say that all the information I need about editors is =
not publicly available (all I can find is a private ivar _editors). So =
this seems impossible.
>=20
> This is not impossible, because I=92ve written and shipped code which =
does this. Unfortunately, this isn=92t code I can share here.
>=20
> You don=92t need access to the bindings=92 private parts. Step back =
and consider the problem you are trying to solve. You don=92t want to =
=93loose=94 the first responder. You can look at the first responder in =
the windows associated with your controller, and remember it (as well as =
a bunch of other details=97the underlying control if it is a field =
editor, visible range, selection ranges, etc.) and restore it after =
committing editing. A bit tedious, but not impossible. (You=92ll end up =
with a fairly generic solution and won=92t have to think about the =
problem again once the edge cases are worked out.)
>=20
> =97Jim
>=20

This makes no sense to me. An NSController does not even have *any* =
properties, let alone a window. It's not an interface element. And =
NSObjectController only knows (publicly) about things it binds to (its =
content or selection), but what is needed is the objects that bind *to* =
it. There's no API for that. So I really fail to see how you could have =
done this without using SPI.

And I know the tedious update part, I already do that for non-binding =
situations.

Christiaan