在iPhone上查找UILabel中特定字符的位置
我有一个UILabel与一些文字,说“你好世界abcdefg”的标签可以有多行,不同的字体大小等 问题:如何找到此UILabel中所有字母“d”的坐标 合乎逻辑的第一步是找到这些字符在字符串(UILabel.text)中的位置,但当它实际绘制在屏幕上时,如何将其转换为坐标在iPhone上查找UILabel中特定字符的位置,iphone,coordinates,uilabel,character,cgpoint,Iphone,Coordinates,Uilabel,Character,Cgpoint,我有一个UILabel与一些文字,说“你好世界abcdefg”的标签可以有多行,不同的字体大小等 问题:如何找到此UILabel中所有字母“d”的坐标 合乎逻辑的第一步是找到这些字符在字符串(UILabel.text)中的位置,但当它实际绘制在屏幕上时,如何将其转换为坐标 我们的想法是找到这些坐标,然后在该字符的上方绘制自定义图形(基本上是用自定义图像覆盖它)iPhone上测量文本的基本工具位于UIStringDrawing.h中,但它们都不能满足您的需要。基本上,您必须一次遍历一个字符的子字符
我们的想法是找到这些坐标,然后在该字符的上方绘制自定义图形(基本上是用自定义图像覆盖它)iPhone上测量文本的基本工具位于
UIStringDrawing.h
中,但它们都不能满足您的需要。基本上,您必须一次遍历一个字符的子字符串。换行(结果较高)时,在最后一个未换行的字符后拆分,并将换行高度添加到y坐标
- (CGSize)sizeWithFont:(UIFont *)font forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode;
自从iOS 7.0问世以来,方法发生了变化。试试这个
- (CGFloat)charactersOffsetBeforeDayPartOfLabel {
NSRange range = [[self stringFromDate:self.currentDate] rangeOfString:[NSString stringWithFormat:@"%i",[self dayFromDate:self.currentDate]]];
NSString *chars = [[self stringFromDate:self.currentDate] substringToIndex:range.location];
NSMutableArray *arrayOfChars = [[NSMutableArray alloc]init];
[chars enumerateSubstringsInRange:NSMakeRange(0, [chars length]) options:(NSStringEnumerationByComposedCharacterSequences) usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
[arrayOfChars addObject:substring];
}];
CGFloat charsOffsetTotal = 0;
for (NSString *i in arrayOfChars){
NSDictionary *attributes = @{NSFontAttributeName: [UIFont fontWithName:@"Helvetica Neue" size:16.0f]};
charsOffsetTotal += [i sizeWithAttributes:attributes].width;
}
return charsOffsetTotal;
}
给你:
fileprivate let selfSizing = UILabel()
class DualColorLabel: UILabel
{
var filled: UIColor?
var unfilled: UIColor?
var origin: String?
var widths: [CGFloat] = []
var fuckupLockup = false
override var text: String? {
didSet {
if fuckupLockup {
print ("SDBOFLAG-13822 wtf?")
}
}
}
func setupColorsAndText(filled: UIColor,
unfilled: UIColor)
{
self.filled = filled
self.unfilled = unfilled
guard let text = origin, text.count > 0 else {
assertionFailure("usage error")
return
}
guard font != nil else {
usageError()
return
}
for index in 1...text.count {
let s = String.Index(utf16Offset: 0, in: text)
let e = String.Index(utf16Offset: index, in: text)
let beginning = text[s..<e]
let p = String(beginning)
selfSizing.font = font
selfSizing.text = p
let size = selfSizing.sizeThatFits(CGSize(width: CGFloat.greatestFiniteMagnitude, height: CGFloat.greatestFiniteMagnitude))
let width = size.width
widths.append(width)
}
}
func setupfill(adjusted: CGRect)
{
assert(adjusted.origin.x <= 0, "fixed this code for fill in the middle: currently supported only fill at start")
let endOffset = adjusted.width + adjusted.origin.x
guard let font = self.font else {
usageError()
return
}
guard let origin = origin, let filled = filled,
let unfilled = unfilled else {
usageError()
return
}
var idx = String.Index(utf16Offset: origin.count, in: origin)
for (index, width) in widths.enumerated() {
if endOffset < width {
idx = String.Index(utf16Offset: index, in: origin)
print ("SDBOFLAG-13822 index \(index) for text \(origin)")
break
}
}
let total = NSMutableAttributedString()
do {
let s = String.Index(utf16Offset: 0, in: origin)
let beginning = origin[s..<idx]
let p = String(beginning)
print("SDBOFLAG-13822 filled text \(p)")
let filledAttributes:
[NSAttributedString.Key : Any] = [NSAttributedString.Key.foregroundColor:
// UIColor.yellow,
filled,
NSAttributedString.Key.font:
font
]
let filledPortion = NSAttributedString(string: p, attributes: filledAttributes)
total.append(filledPortion)
}
let unfilledAttributes:
[NSAttributedString.Key : Any] = [NSAttributedString.Key.foregroundColor:
// UIColor.blue,
unfilled,
NSAttributedString.Key.font: font]
let e = String.Index(utf16Offset: origin.count, in: origin)
let ending = origin[idx..<e]
let str = String(ending)
print("SDBOFLAG-13822 unfilled text \(str)")
let unfilledPortion = NSAttributedString(string: str, attributes: unfilledAttributes)
total.append(unfilledPortion)
self.attributedText = total
fuckupLockup = true
}
/*
// Only override draw() if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
override func draw(_ rect: CGRect) {
// Drawing code
}
*/
}
func usageError()
{
assertionFailure("usage error")
}
fileprivate let selfSizing=UILabel()
类别DualColorLabel:UILabel
{
变量填充:UIColor?
var未填充:UIColor?
变量来源:字符串?
变量宽度:[CGFloat]=[]
var fuckupLockup=错误
覆盖变量文本:字符串{
迪塞特{
如果他妈的搞砸了{
打印(“SDBOFLAG-13822 wtf?”)
}
}
}
func设置颜色和文本(填充:UIColor,
未填充:UIColor)
{
自填的
self.unfilled=未填充
guard let text=原点,text.count>0其他{
断言失败(“使用错误”)
返回
}
防护字体!=无其他字体{
usageError()
返回
}
对于1…text.count中的索引{
设s=String.Index(utf16Offset:0,in:text)
设e=String.Index(utf16Offset:Index,in:text)
让beging=text[s..这提供了您可能需要的部分内容。唉,这可能需要做一些工作,但我想这是最好的选择。谢谢您的回答!为什么您要计算每个字符的大小?为什么不立即获得整个子字符串的大小?