gpt4 book ai didi

ios - 从点击获取 UILabel 中的字符索引

转载 作者:可可西里 更新时间:2023-11-01 05:04:22 25 4
gpt4 key购买 nike

我想获取 UILabel 上点击字符的索引。我已经子类化了一个 UILabel。在我的 awakeFromNib() 中,我有这个:

    layoutManager = NSLayoutManager()
textStorage = NSTextStorage(attributedString: self.attributedText)
textStorage.addLayoutManager(layoutManager)

textContainer = NSTextContainer(size: CGSizeMake(self.frame.size.width, self.frame.size.height))
textContainer.lineFragmentPadding = 0
textContainer.maximumNumberOfLines = self.numberOfLines
textContainer.lineBreakMode = self.lineBreakMode
textContainer.size = self.frame.size

layoutManager.addTextContainer(textContainer)

对于标签的前 5 个字符,它按照我想要的方式工作,因为我点击第一个字符,在我的 touchesEnded 中,我得到的索引为 0:

var touchedCharacterIndex = layoutManager.characterIndexForPoint(touch.locationInView(self), inTextContainer: textContainer, fractionOfDistanceBetweenInsertionPoints: nil)

但是当我点击 UILabel 前四个字符之后的任何地方时,我得到的不是 4 就是 0,这是不正确的。

谢谢,

更新

根据评论中的建议,我添加了这个:

 func updateTextStorage() {
if let attributedText = self.attributedText {
textStorage = NSTextStorage(attributedString: attributedText)
}
textStorage?.addLayoutManager(layoutManager)

textContainer = NSTextContainer(size: CGSizeMake(self.frame.size.width, self.frame.size.height))
textContainer?.lineFragmentPadding = 7
textContainer?.maximumNumberOfLines = self.numberOfLines
textContainer?.lineBreakMode = self.lineBreakMode
textContainer?.size = self.bounds.size

layoutManager.addTextContainer(textContainer!)
layoutManager.textStorage = textStorage
}

我在 layoutSubviews()awakFromNibboundsframe 的 setter 中调用它>attributedTexttext

它现在给我一些奇怪的索引,比如如果文本长度是 21,点击第一个字母给我 6。

最佳答案

TLDR:您得到了一些奇怪的索引,因为您的 layoutManager 看到的字符串布局与您在屏幕上实际看到的不同。


您从以下位置获取了一些奇怪的索引:

- (NSUInteger)characterIndexForPoint:(CGPoint)point
inTextContainer:(NSTextContainer *)container
fractionOfDistanceBetweenInsertionPoints:(nullable CGFloat *)partialFraction;

因为您自己的 layoutManager 必须与系统 UILabel 的内部 layoutManager 同步。这意味着当您在标签上设置字体、大小等时,内部 layoutManager 知道这些,因为它由 UILabel 处理,但是您的 layoutManager 实例没有。

因此布局管理器“看到”的文本布局与屏幕上标签呈现的实际文本(我敢打赌是默认字体和大小)处于不同的位置。

复杂的部分是保持这些属性同步,你可以做的是在你的属性文本上设置它们,比如:

[mutableAttributedString addAttribute:NSFontAttributeName 
value:self.font
range:NSMakeRange(0, mutableAttributedString.string.length)];

并将此属性字符串传递给您的 NSTextStorage 实例。这为我解决了所有问题。


信息:为了帮助您调试,您可以使用 layoutManager 呈现字符串“seen”:

- (void)drawTextInRect:(CGRect)rect
{
[super drawTextInRect:rect];
[self.layoutManager drawGlyphsForGlyphRange:NSMakeRange(0, self.textStorage.length) atPoint:CGPointMake(0, 0)];
}

如果您看到 2 根弦相互重叠并出现一些故障,这就是您的问题所在。如果你只能看到一个,那应该是因为它们完全对齐,你很好!

关于ios - 从点击获取 UILabel 中的字符索引,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31008267/

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