【问题标题】:How to use NSTextFinder programmatically?如何以编程方式使用 NSTextFinder?
【发布时间】:2017-10-18 19:08:21
【问题描述】:

我想在NSTextView 中执行“查找”操作,而不使用内置的查找栏。如何以编程方式设置搜索字符串并在文本视图中突出显示结果?

这适用于 macOS 10.12 及更高版本。

FWIW,这不是这个问题的重复:NSTextFinder set search string and clear visual feedback programatically

这个问题是关于以编程方式控制查找栏 UI,清除以前的查找结果或填充查找栏搜索字段。

这个问题是关于在不使用查找栏 UI 的情况下以编程方式调用“查找”操作。

【问题讨论】:

  • 不是重复的。请参阅编辑。
  • 先设置搜索字符串,然后调用performAction:
  • 如何以编程方式设置搜索字符串?我尝试像在另一个问题中一样将其放入查找粘贴板,然后调用[textFinder performAction:NSTextFinderActionSetSearchString],但除非我显示查找栏 UI,否则 NSTextFinder 不会使用我的字符串。如果我不显示查找栏,仍然会使用之前设置的搜索字符串。
  • 好吧,不是抄袭,答案不行。我试试看。

标签: macos cocoa nstextview


【解决方案1】:

这是我的测试代码(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

【讨论】:

  • 谢谢。这让我指出了正确的方向,现在我可以玩弄它了。我没有想到要递归地在 findBar 中搜索 searchField 以填充它。你知道NSTextFinderAction NSTextFinderActionSetSearchString 是做什么的吗?我认为这是设置搜索字符串的方法,但不知道如何提供搜索字符串作为参数。
  • NSTextFinderActionSetSearchString 使用选择进行查找(Command-E)。
猜你喜欢
  • 1970-01-01
  • 2012-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多