Re: Calling commitEditing text field loses focus

Jim Correia <[email protected]> Wed, 21 Dec 2011 08:08:58 -0800
Newsgroups gmane.comp.macosx.devel
Message-ID <[email protected]>
On Dec 21, 2011, at 3:15 AM, Christiaan Hofman wrote:

>> 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.

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.)

>> 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?

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.)

>> 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.

It=92s good for dramatic effect, but calling bindings useless because it =
gets this aspect wrong is kind of harsh.=20

>> 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.

This is not impossible, because I=92ve written and shipped code which =
does this. Unfortunately, this isn=92t code I can share here.

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.)

=97Jim