Re: Find functions disabled while NSSearchField is first responder.
Re: Find functions disabled while NSSearchField is first responder.
- Subject: Re: Find functions disabled while NSSearchField is first responder.
- From: Antonio Nunes <email@hidden>
- Date: Sat, 27 Apr 2013 10:39:10 +0200
On 27 Apr, 2013, at 08:04 , Antonio Nunes <email@hidden> wrote:
> On 25 Apr, 2013, at 18:21 , Antonio Nunes <email@hidden> wrote:
>
>>> I have an NSSearchField, and a menu bar submenu with the standard Find items. When the search field receives some input, it performs its action and an array controller is filled with search results. Now, while the search field is the first responder, none of the Find items are enabled, so it is impossible to issue, say a Find Next command. The Find functions perform fine when just about any other item in the document window is first responder. I find that surprising, but, more importantly, I cannot find a way to get the Find functions to work, while the search command has focus. What am I missing?
>>
>> I added a search field to a small test project, to see if it works correctly in a less complicated setup, but to no avail. The Find menu items are still disabled. Some more googling (previous queries did not yield any relevant info), showed me that this issue has bitten others before, but no solutions appear to have been put forward.
>>
>> I've checked the responder chain, and tried to catch calls to validateMenuItem and validateUserInterfaceItem:, to see if I can find out the point at which these items are disabled. But the break points don't even trigger. When I check the window for its first responder, when the search field is receiving input, it returns the document window, not the search field. The document window though, has its own implementation of validateMenuItem:, but that is never called.
>>
>> How can I find out where the validation for performFindPanelAction: fails?
>
> Finally managed to solve this, and this is how I did it: (doesn't feel clean or proper, but it works. If anyone knows of a better way to do this, I'm all ears.)
>
> - In my NSDocument subclass, return a custom object (NSTextView subclass) for the NSFieldEditor when the search field is activated:
>
> - (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)client
> {
> static NMD_SearchTextView *searchFieldEditor;
>
> if ( client == self.searchField ) {
> if ( nil == searchFieldEditor ) {
> searchFieldEditor = [[NMD_SearchTextView alloc] initWithFrame:NSZeroRect];
> searchFieldEditor.document = self; // The object has a document property to point to the NSDocument object, since we'll need that later.
> }
> return searchFieldEditor;
> }
> return nil;
> }
Oh dear, as someone pointed out off-list, there's a bug here: the document is only assigned once, when the searchFieldEditor variable is set the first time. The document should be assigned on every call:
if ( client == self.searchField ) {
if ( nil == searchFieldEditor ) {
searchFieldEditor = [[NMD_SearchTextView alloc] initWithFrame:NSZeroRect];
}
searchFieldEditor.document = self; // The object has a document property to point to the NSDocument object, since we'll need that later.
return searchFieldEditor;
}
return nil;
}
> - Implement validateMenuItem: on the subclass to enable the relevant menu items.
>
> - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
> {
> if ( menuItem.action == @selector(performFindPanelAction:)) {
> return menuItem.tag != NSFindPanelActionSetFindString; // No use allowing "Use Selection for Find", since it will always be equal to the current find string, where it exists.
> } else {
> return [super validateMenuItem:menuItem];
> }
> }
>
> - Implement performFindPanelAction: to forward the action to the document.
>
> - (void)performFindPanelAction:(id)sender
> {
> [self.document performFindPanelAction:sender];
> }
_______________________________________________
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