8

I’m trying to replicate the behaviour of the search field in iTunes, for looking up stock symbols and names. Specifically, as you start typing in the search field a popover appears with the filtered items. For the most part I have this working however what I can’t replicate is the way it handles first responder enter image description here

I have my popover appear after three characters are entered. At this point the NSSearchField would lose first responder status and therefore I could no longer continue typing. The behaviour I would like is the ability to continue typing after the popover appears if scrolling through the items with the arrow keys, and then resume typing, you would continue from the last character in the Search field.

What I tried is subclassing NSTextView (use this as the custom field editor for the NSSearchField) and overriding

- (BOOL)resignFirstResponder 

By simply returning NO, I can continue typing once the popover appears, but obviously I can’t select any of the items in the popover. So i tried the following, which returns YES if the down arrow or a mousedown event occurs.

@interface SBCustomFieldEditor ()
{
    BOOL resignFirstRepond;
}
@end

@implementation SBCustomFieldEditor

- (id)initWithFrame:(NSRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code here.
        resignFirstRepond = NO;
    }
    return self;
}

- (BOOL)resignFirstResponder
{
    return resignFirstRepond;
}

- (void)keyDown:(NSEvent *)theEvent
{
    if ([theEvent keyCode] == 125) {
        resignFirstRepond = YES;
        [self resignFirstResponder];
    }
    [super keyDown:theEvent];
}

- (void)mouseDown:(NSEvent *)theEvent
{
    resignFirstRepond = YES;
    [self resignFirstResponder];
}

This works for the mousedown event, but not the keydown event, furthermore this doesn’t address the issue, when the user resumes typing.

Any suggestions?

Cory
  • 2,302
  • 20
  • 33
  • Have you tried setting NSPopoverBehaviorApplicationDefined as behavior. I think the other 2 behaviors may rely on first responder switch to handle closing the popover properly. Additionally, I assume you have already tried to set the first responder status manually to the text field after the popover appeared. – Mike Lischke Dec 23 '13 at 09:27
  • @MikeLischke When you say "manually" do you mean clicking on the search field while the app is running? if so, yes that works. or do you mean using something like setNextResponder? – Cory Dec 23 '13 at 11:19
  • no I mean `NSWindow makeFirstResponder:`. You can call this after you made the popover visible (schedule it to the next run loop via `performSelector:withObject:afterDelay:0`). – Mike Lischke Dec 23 '13 at 14:20
  • 1
    Any progress on this issue? I'm stuck with the same problem. – Quxflux Jan 14 '14 at 09:50
  • 3
    @Lukas I ended up ditching the NSPopOver and using a custom window, I used the example found here(https://developer.apple.com/library/mac/samplecode/CustomMenus/Introduction/Intro.html#//apple_ref/doc/uid/DTS40010056) along with WWDC session 145 video. – Cory Jan 15 '14 at 23:11
  • 1
    @Cory Thanks. I also posted a question with someone providing a working answer here: http://stackoverflow.com/questions/21110622/force-nspopover-to-not-become-first-responder-with-nstokenfield/21111462 – Quxflux Jan 16 '14 at 05:37

1 Answers1

0

In the meantime I found an easy fix. Subclass your text view and implement - (BOOL)canBecomeKeyView. Always return NO there. It will be called only once when the popover is shown. You can work with the text view any time still.

Mike Lischke
  • 48,925
  • 16
  • 119
  • 181