2017-10-18 5 views
1

Je voudrais faire une opération de "recherche" dans un NSTextView sans utiliser la barre de recherche intégrée. Comment puis-je programmer une chaîne de recherche et mettre les résultats en surbrillance dans la vue de texte?Comment utiliser NSTextFinder par programme?

Ceci est pour macOS 10.12 et supérieur.

FWIW, ce n'est pas un double de cette question: NSTextFinder set search string and clear visual feedback programatically

Cette question est sur le contrôle de programmation de l'interface utilisateur de barre de recherche, soit la compensation des résultats de précédents ou peuplant find find champ de recherche bar.

Cette question concerne l'appel d'une opération "find" par programme sans utiliser l'interface utilisateur de la barre de recherche.

+0

double possible de [NSTextFinder mis chaîne de recherche et une rétroaction visuelle claire programatically] (https://stackoverflow.com/questions/13839265/nstextfinder-set -search-string-and-clear-visual-feedback-programatically) – Willeke

+0

Ce n'est pas un doublon. S'il vous plaît voir modifier. – sam

+0

Définissez d'abord la chaîne de recherche, puis appelez "performAction:". – Willeke

Répondre

1

Voici mon code de test (aki, expérimental):

@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

Merci. Cela m'a fait pointer dans la bonne direction et maintenant je peux jouer avec. Il ne m'est pas venu à l'esprit de rechercher récursivement findBar pour searchField afin de le peupler. Savez-vous ce que fait le 'NSTextFinderAction'' NSTextFinderActionSetSearchString'? Je pensais que c'était la façon de définir la chaîne de recherche, mais je n'arrivais pas à comprendre comment fournir une chaîne de recherche en tant qu'argument. – sam

+0

'NSTextFinderActionSetSearchString' utilise la sélection pour la recherche (commande-E). – Willeke