gpt4 book ai didi

ios - 在 NSLayoutManager 中控制自定义文本属性周围的间距

转载 作者:行者123 更新时间:2023-12-01 10:34:30 26 4
gpt4 key购买 nike

我有一个自定义 NSLayoutManager我用来绘制药丸形标记的子类。我为具有自定义属性( TokenAttribute )的子字符串绘制这些标记。我可以画没有问题。

但是,我需要使用我的 TokenAttribute 在范围周围添加一点“填充” (这样 token 的圆角矩形背景就不会与文本相交)。

enter image description here

在上图中,我用橙色绘制了 token 的背景,但我希望在 469 周围有额外的填充。所以背景与文本不符。

我不确定该怎么做。我尝试覆盖 -boundingRectForGlyphRange:inTextContainer:返回具有更多水平填充的边界矩形,但字形的布局似乎实际上并不受此影响。

如何在某些字形/字形范围内提供更多间距?

这是我用来绘制背景的代码,在我的布局管理器子类中:

- (void)drawGlyphsForGlyphRange:(NSRange)glyphsToShow atPoint:(CGPoint)origin {

NSTextStorage *textStorage = self.textStorage;
NSRange glyphRange = glyphsToShow;

while (glyphRange.length > 0) {

NSRange characterRange = [self characterRangeForGlyphRange:glyphRange actualGlyphRange:NULL];
NSRange attributeCharacterRange;
NSRange attributeGlyphRange;

id attribute = [textStorage attribute:LAYScrubbableParameterAttributeName
atIndex:characterRange.location
longestEffectiveRange:&attributeCharacterRange
inRange:characterRange];

attributeGlyphRange = [self glyphRangeForCharacterRange:attributeCharacterRange
actualCharacterRange:NULL];
attributeGlyphRange = NSIntersectionRange(attributeGlyphRange, glyphRange);

if (attribute != nil) {
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);

UIColor *backgroundColor = [UIColor orangeColor];
NSTextContainer *textContainer = self.textContainers[0];
CGRect boundingRect = [self boundingRectForGlyphRange:attributeGlyphRange inTextContainer:textContainer];

// Offset this bounding rect by the `origin` passed in above
// `origin` is the origin of the text container!
// if we don't do this, then bounding rect is incorrectly placed (too high, in my case).
boundingRect.origin.x += origin.x;
boundingRect.origin.y += origin.y;

[backgroundColor setFill];
UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:boundingRect cornerRadius:boundingRect.size.height / 2.0];
[path fill];

[super drawGlyphsForGlyphRange:attributeGlyphRange atPoint:origin];
CGContextRestoreGState(context);

} else {
[super drawGlyphsForGlyphRange:glyphsToShow atPoint:origin];
}

glyphRange.length = NSMaxRange(glyphRange) - NSMaxRange(attributeGlyphRange);
glyphRange.location = NSMaxRange(attributeGlyphRange);
}
}

最佳答案

NSLayoutManagerDelegate 中定义了一些方法,它们用作基于字形的自定义点。

利用

func layoutManager(_ layoutManager: NSLayoutManager, shouldGenerateGlyphs glyphs: UnsafePointer<CGGlyph>, properties props: UnsafePointer<NSLayoutManager.GlyphProperty>, characterIndexes charIndexes: UnsafePointer<Int>, font aFont: NSFont, forGlyphRange glyphRange: NSRange) -> Int

识别与您感兴趣的范围周围的空白相关联的字形,并通过将它们在 props 数组中的值更改为 NSLayoutManager.GlyphProperty.controlCharacter 来标记这些字形。
然后将此更改后的数组传递给

NSLayoutManager.setGlyphs(_:properties:characterIndexes:font:forGlyphRange:)

之后,您可以实现

func layoutManager(_ layoutManager: NSLayoutManager, shouldUse action: NSLayoutManager.ControlCharacterAction, forControlCharacterAt charIndex: Int) -> NSLayoutManager.ControlCharacterAction

再次识别感兴趣的字形并返回预定义的操作:

NSLayoutManager.ControlCharacterAction.whitespace

最后,这可以让您实现

func layoutManager(_ layoutManager: NSLayoutManager, boundingBoxForControlGlyphAt glyphIndex: Int, for textContainer: NSTextContainer, proposedLineFragment proposedRect: NSRect, glyphPosition: NSPoint, characterIndex charIndex: Int) -> NSRect

更改用于字形的边界框。只需返回适当的尺寸。这将对以下布局机制产生影响。

祝你好运!

关于ios - 在 NSLayoutManager 中控制自定义文本属性周围的间距,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34504031/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com