2017-10-18 97 views
1

我想在不使用內置查找欄的情況下在NSTextView中執行「查找」操作。如何以編程方式設置搜索字符串並在文本視圖中突出顯示結果?如何以編程方式使用NSTextFinder?

這是針對macOS 10.12及更高版本的。

FWIW,這是不是這個問題的一個副本:NSTextFinder set search string and clear visual feedback programatically

這個問題是關於編程控制查找欄UI,無論是以前的結算查找結果或填充查找欄搜索領域。

這個問題是關於調用一個「查找」操作編程方式,根本不使用查找欄用戶界面。

+0

的[NSTextFinder設置搜索字符串和編程清晰的視覺反饋](可能的複製https://stackoverflow.com/questions/13839265/nstextfinder-set -search-string-and-clear-visual-feedback-programatically) – Willeke

+0

這不是重複的。請參閱編輯。 – sam

+0

首先設置搜索字符串,然後調用'performAction:'。 – Willeke

回答

1

這裏是我的測試代碼(哈克,實驗組):

@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

謝謝。這讓我指出了正確的方向,現在我可以玩弄它。我沒有想到爲了填充它而遞歸搜索searchFar的searchField。你知道'NSTextFinderAction' NSTextFinderActionSetSearchString嗎?我認爲這是設置搜索字符串的方式,但無法弄清楚如何提供搜索字符串作爲參數。 – sam

+0

'NSTextFinderActionSetSearchString'確實使用選擇(Command-E)。 – Willeke