如何以编程方式使用 NSTextFinder?
How to use NSTextFinder programmatically?
我想在 NSTextView
中执行 "find" 操作而不使用内置查找栏。如何以编程方式设置搜索字符串并在文本视图中突出显示结果?
这适用于 macOS 10.12 及更高版本。
FWIW,这不是这个问题的重复:NSTextFinder set search string and clear visual feedback programatically
这个问题是关于以编程方式控制查找栏 UI,清除以前的查找结果或填充查找栏搜索字段。
这个问题是关于在根本不使用查找栏 UI 的情况下以编程方式调用 "find" 操作。
这是我的测试代码(hacky,实验):
@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
我想在 NSTextView
中执行 "find" 操作而不使用内置查找栏。如何以编程方式设置搜索字符串并在文本视图中突出显示结果?
这适用于 macOS 10.12 及更高版本。
FWIW,这不是这个问题的重复:NSTextFinder set search string and clear visual feedback programatically
这个问题是关于以编程方式控制查找栏 UI,清除以前的查找结果或填充查找栏搜索字段。
这个问题是关于在根本不使用查找栏 UI 的情况下以编程方式调用 "find" 操作。
这是我的测试代码(hacky,实验):
@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