NSTextView selection highlights all characters even paragraph indents

你说的曾经没有我的故事 提交于 2019-12-10 10:08:20

问题


Can't find any clue how to manage this.

By default, NSTextView selection highlights the whole size of its text container. It ignores line spacing, head or tail indents etc. But in Pages app selection doesn't highlight those ancillary parts, it highlight characters ONLY. And it highlights all the height of the line even if text container's height is smaller (paragraph spacing before and after).

I want to implement that behavior but can't understand where to begin. I've searched here, I've searched Apple docs, I've tried sample projects. Nothing.

Maybe someone can guide me in the right direction? Thanks!


回答1:


I found that hamstergene's answer isn't correct. In fact, NSTextView highlights its text container lines all over their bounds.

So, if you use paragraph's head indents then a leading the text empty space will be highlighted. And if you select EOL character then the tail of the text container will be highlighted.

My solution was to nullify head and tail indents of the paragraph style (I cache them in the private variable and put them back when my text storage is accessed for printing) and simply adjust frame of the text container line via overrided lineFragmentRectForProposedRect: atIndex: writingDirection: remainingRect method of my NSTextContainer subclass.

But then I found much proper way. Just override func fillBackgroundRectArray(_ rectArray: UnsafePointer<NSRect>, count rectCount: Int, forCharacterRange charRange: NSRange, color: NSColor) of the NSLayoutManager, calculate your rects and call super with those rects. And if you calculated selection rectangles properly, you'll get the exact selection behavior like in Apple Pages or MS Word.

Simple and easy!




回答2:


We can only speculate what closed-source Pages use, but I doubt it is using NSTextView — as a word processor it has to be using much more advanced custom solution.

Start from Cocoa Text Architecture Guide, you are primarily interested in NSLayoutManager class (which is accompanied by NSTextContainer and NSTextStorage).

NSTextView probably implements its selection via temporary attributes (-[NSLayoutManager addTemporaryAttribute:value:forCharacterRange:]). If you subclass NSTextView and intercept every selection changing event, you should be able to detect and remove temporary attribute(s) responsible for displaying selection from newline characters without interfering with text view's logical selection range.

If by some reason the above suggestion doesn't work, it is always possible to reimplement NSTextView from scratch, using NSLayoutManager to handle all layout and drawing. NSLayoutManager handles all unicode/bidi quirks, giving out precise pixel coordinates of glyph runs and individual glyphs, as well as methods to draw them. The temporary attributes may be inadequate to implement different selection height; in that case you should be able to draw selection yourself (on the background under text glyphs). That is sure gonna be a lot of work for such a little UI detail, though.



来源:https://stackoverflow.com/questions/24407203/nstextview-selection-highlights-all-characters-even-paragraph-indents

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!