NSLayoutManager 字形生成和插入符号位置
NSLayoutManager glyph generation and caret position
我有一个文本编辑器应用程序,它使用 Markdown 样式的格式。当 caret/selection 不在相应行时,格式化字符被隐藏。
我成功地使用 NSLayoutManagerDelegate
中的 shouldGenerateGlyphs:
方法来操纵 NSTextView
上绘制的内容。我使用的是纯委托,没有对布局管理器本身进行子类化。
但是,我无法理解如何在字形重新生成后正确定位插入符号。选择更改后,我将调用一个方法(此处称为 hideAndShowMarkup
),该方法为当前编辑的行和之前选择的行重新生成字形。因为在屏幕上添加了一些字形,所以插入符号呈现错误。
-(void)hideAndShowMarkup {
[self.layoutManager invalidateGlyphsForCharacterRange:currentLine.range changeInLength:0 actualCharacterRange:nil];
[self.layoutManager invalidateGlyphsForCharacterRange:prevLine.range changeInLength:0 actualCharacterRange:nil];
[self.layoutManager ensureGlyphsForCharacterRange:currentLine.range];
[self.layoutManager ensureGlyphsForCharacterRange:prevLine.range];
[self updateInsertionPointStateAndRestartTimer:YES];
}
updateInsertionPoint...
在这里不起作用,因为确保字形似乎 运行 异步。我也试过在 didCompleteLayoutForTextContainer:
委托方法中调用它,但没有效果。
有没有办法检测字形实际绘制的时间,并确保之后插入点的位置?
NSLayoutManager
的文档出奇地少,要了解其内部工作原理,需要查看随机 public 存储库中的实现。
要更改范围内的字形并使插入符位置正确,您首先需要使两个更改范围的字形无效,然后使范围内的 layout 无效插入符号即将位于。
然后,在确保有当前图形上下文后,可以同步重绘字形。之后更新插入点就正常了
在下面的示例中,我有两个对象,line
和 prevLine
,它们包含插入符号现在所在的行和一个插入符号移开的范围。
-(void)hideAndShowMarkup {
[self.layoutManager invalidateGlyphsForCharacterRange:line.range changeInLength:0 actualCharacterRange:nil];
[self.layoutManager invalidateGlyphsForCharacterRange:prevLine.range changeInLength:0 actualCharacterRange:nil];
[self.layoutManager invalidateLayoutForCharacterRange:line.range actualCharacterRange:nil];
if (NSGraphicsContext.currentContext) {
[self.layoutManager drawGlyphsForGlyphRange:line.range atPoint:self.frame.origin];
[self.layoutManager drawGlyphsForGlyphRange:prevLine.range atPoint:self.frame.origin];
}
[self updateInsertionPointStateAndRestartTimer:NO];
}
我有一个文本编辑器应用程序,它使用 Markdown 样式的格式。当 caret/selection 不在相应行时,格式化字符被隐藏。
我成功地使用 NSLayoutManagerDelegate
中的 shouldGenerateGlyphs:
方法来操纵 NSTextView
上绘制的内容。我使用的是纯委托,没有对布局管理器本身进行子类化。
但是,我无法理解如何在字形重新生成后正确定位插入符号。选择更改后,我将调用一个方法(此处称为 hideAndShowMarkup
),该方法为当前编辑的行和之前选择的行重新生成字形。因为在屏幕上添加了一些字形,所以插入符号呈现错误。
-(void)hideAndShowMarkup {
[self.layoutManager invalidateGlyphsForCharacterRange:currentLine.range changeInLength:0 actualCharacterRange:nil];
[self.layoutManager invalidateGlyphsForCharacterRange:prevLine.range changeInLength:0 actualCharacterRange:nil];
[self.layoutManager ensureGlyphsForCharacterRange:currentLine.range];
[self.layoutManager ensureGlyphsForCharacterRange:prevLine.range];
[self updateInsertionPointStateAndRestartTimer:YES];
}
updateInsertionPoint...
在这里不起作用,因为确保字形似乎 运行 异步。我也试过在 didCompleteLayoutForTextContainer:
委托方法中调用它,但没有效果。
有没有办法检测字形实际绘制的时间,并确保之后插入点的位置?
NSLayoutManager
的文档出奇地少,要了解其内部工作原理,需要查看随机 public 存储库中的实现。
要更改范围内的字形并使插入符位置正确,您首先需要使两个更改范围的字形无效,然后使范围内的 layout 无效插入符号即将位于。
然后,在确保有当前图形上下文后,可以同步重绘字形。之后更新插入点就正常了
在下面的示例中,我有两个对象,line
和 prevLine
,它们包含插入符号现在所在的行和一个插入符号移开的范围。
-(void)hideAndShowMarkup {
[self.layoutManager invalidateGlyphsForCharacterRange:line.range changeInLength:0 actualCharacterRange:nil];
[self.layoutManager invalidateGlyphsForCharacterRange:prevLine.range changeInLength:0 actualCharacterRange:nil];
[self.layoutManager invalidateLayoutForCharacterRange:line.range actualCharacterRange:nil];
if (NSGraphicsContext.currentContext) {
[self.layoutManager drawGlyphsForGlyphRange:line.range atPoint:self.frame.origin];
[self.layoutManager drawGlyphsForGlyphRange:prevLine.range atPoint:self.frame.origin];
}
[self updateInsertionPointStateAndRestartTimer:NO];
}