2017-10-18 9 views
1

Ich möchte eine "Suche" -Operation in einem NSTextView ohne die integrierte Suchleiste zu tun. Wie programmiere ich eine Suchzeichenfolge und lasse die Ergebnisse in der Textansicht hervorheben?Wie programmiere ich NSTextFinder?

Dies ist für Mac OS 10.12 und höher.

FWIW, ist dies nicht ein Duplikat dieser Frage: NSTextFinder set search string and clear visual feedback programatically

Diese Frage zu programmatisch die Suchleiste UI steuern, entweder vorherigen Fund Ergebnisse Clearing oder die Suchleiste Suchfeld bevölkern.

Bei dieser Frage geht es darum, eine "Find" -Operation programmgesteuert aufzurufen, ohne die Benutzeroberfläche der Suchleiste zu verwenden.

+0

Mögliches Duplikat [NSTextFinder gesetzt Suchbegriff und klares visuelles Feedback programmatisch] (https://stackoverflow.com/questions/13839265/nstextfinder-set -search-string-and-clear-visual-feedback-programmatisch) – Willeke

+0

Es ist kein Duplikat. Bitte siehe Bearbeiten. – sam

+0

Setzen Sie zuerst die Suchzeichenfolge und rufen Sie 'performAction:' auf. – Willeke

Antwort

1

Hier ist mein Test-Code (Hacky, experimentell):

@interface ViewController() 

@property (strong) NSTextFinder *textFinder; 
@property (weak) IBOutlet NSTextView *textView; // find Uses Bar, Incremental Searching is on 
@property (weak) NSView *myFindBarView; 
@property (weak) IBOutlet NSView *findBarContainerView; // hidden 
@property BOOL barVisible; 

@end 

@implementation ViewController 

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    self.textFinder = [[NSTextFinder alloc] init]; 
    self.textFinder.incrementalSearchingEnabled = YES; 
    self.textFinder.incrementalSearchingShouldDimContentView = YES; 
    self.textFinder.client = (id<NSTextFinderClient>)self.textView; 
    self.textFinder.findBarContainer = self; 
    [self.textFinder performAction:NSTextFinderActionShowFindInterface]; 
} 

- (IBAction)testSearchString:(id)sender { 
    // action method of a Test button, searches for "found" 
    [self.textFinder cancelFindIndicator]; 

    // search the subviews for a view of class NSSearchField 
    __block __weak NSSearchField *(^weak_findSearchField)(NSView *); 
    NSSearchField *(^findSearchField)(NSView *); 
    weak_findSearchField = findSearchField = ^(NSView *view) { 
     if ([view isKindOfClass:[NSSearchField class]]) 
      return (NSSearchField *)view; 
     __block NSSearchField *foundView = nil; 
     [view.subviews enumerateObjectsUsingBlock:^(NSView *subview, NSUInteger idx, BOOL *stop) { 
      foundView = weak_findSearchField(subview); 
      if (foundView) 
       *stop = YES; 
     }]; 
     return foundView; 
    }; 

    NSSearchField *searchField = findSearchField(self.myFindBarView); 
    [searchField setStringValue:@"found"]; 
    // execute the action of the search field to confirm the new value and do a search 
    [searchField sendAction:searchField.action to:searchField.target]; 
    /* add to select all 
    [self.textFinder performAction:NSTextFinderActionSelectAll]; 
    */ 
} 

// NSTextFinderBarContainer 

- (void)findBarViewDidChangeHeight { 
} 

- (NSView *)findBarView { 
    return self.myFindBarView; 
} 

- (void)setFindBarView:(NSView *)theView { 
    self.myFindBarView = theView; 
    if (theView) { 
     NSRect frame = theView.frame; 
     frame.size.width = self.findBarContainerView.bounds.size.width; 
     theView.frame = frame; 
     [self.findBarContainerView addSubview:theView]; 
    } 
} 

- (NSView *)contentView { 
    return self.textView.enclosingScrollView.contentView; 
} 

- (BOOL)isFindBarVisible { 
    return self.barVisible; 
} 

- (void)setFindBarVisible:(BOOL)theVisible { 
    self.barVisible = theVisible; 
} 

@end 
+0

Danke. Das hat mich in die richtige Richtung gelenkt und jetzt kann ich damit herumspielen. Es ist mir nicht in den Sinn gekommen, die findBar rekursiv nach dem searchField zu durchsuchen, um es zu füllen. Weißt du was der 'NSTextFinderAction'' NSTextFinderActionSetSearchString' macht? Ich dachte, das wäre der Weg, um den Suchstring zu setzen, aber ich konnte nicht herausfinden, wie man einen Suchstring als Argument zur Verfügung stellt. – sam

+0

'NSTextFinderActionSetSearchString' verwendet Auswahl für Suche (Befehl-E). – Willeke