Draw a border around a part of NSAttributedString

2019-06-05 18:59发布

I'm developing a MacOs application and have to implement my own search functional due to custom interface.

So the question is - how can a draw a border around a part of NSAttributedString in NSTextView to display search result (just how it's done in TextEdit app). Please check the desired look on the attached image:

http://d.pr/i/w8wP

[UPDATE]

Due to custom interface requirements I can't use NSTextViews's setUsesFindBar: and setUsesFindPanel:. The interface has a custom NSSearchField, which should perform search in a textView.

I've got familiar with performTextFinderAction:, but how do I trigger it on a textView with the NSSearchField value?

2条回答
手持菜刀,她持情操
2楼-- · 2019-06-05 19:33

For what you want to do you need not use the IB or any find operation, because an NSTextView object (let's say its name is myTextView) does it all. You have to first create a range of characters you want to highlight and then tell myTextView to do it:

NSRange charRange = NSMakeRange( location length );   // whatever you want
[myTextView showFindIndicatorForRange:charRange];

If the selection is within a NSScrollView this selection should be made visible. Do this before you call -showFindIndicatorForRange (see the doc under NSTextView):

NSLayoutManager *layout = [myTextView layoutManager];
NSRect rect = [layout boundingRectForGlyphRange:charRange
                                inTextContainer:[myTextView textContainer] ];
[myTextView scrollRectToVisible:rect];

And now an extension to show as many highlighted strings as you want. Let us assume we want to mark all characters at a prime number position. (I do not know what that shall be good for, but why not?). We create an NSArray with the corresponding ranges: (pseudocode!, the ranges must be NSValues! )

allRanges = { (1,1) (2,1) (3,1) (5,1) (7,1) etc.}

All can now be selected together:

[myTextView setSelectedRanges:allRanges];
// select the 3th (zero based) entry
[showFindIndicatorForRange:[allRanges objectAtIndex:3];

This is used within the find mechanism, but it also works without using any finding process.

查看更多
一纸荒年 Trace。
3楼-- · 2019-06-05 19:50

In interface builder, you can set the "Find" property to control where the built in find/replace bar is displayed. To do a find action in code, invoke performFindPanelAction: on the NSTextView.

查看更多
登录 后发表回答