UILabel - видимая часть текста
Есть ли способ получить видимую часть текста в слове wrapped UILabel
? Я имею в виду именно последний видимый символ?
Я хотел бы сделать две метки, округляющие изображение, и хотел бы продолжить текст, который был неправым для первой метки на втором.
Я знаю [NSString sizeWithFont...]
, но что-то изменилось, как [NSString stringVisibleInRect: withFont:...]
?: -)
Спасибо заранее.
Ответы
Ответ 1
Вы можете использовать категорию для расширения NSString и создать метод, который вы упомянули
@interface NSString (visibleText)
- (NSString*)stringVisibleInRect:(CGRect)rect withFont:(UIFont*)font;
@end
@implementation NSString (visibleText)
- (NSString*)stringVisibleInRect:(CGRect)rect withFont:(UIFont*)font
{
NSString *visibleString = @"";
for (int i = 1; i <= self.length; i++)
{
NSString *testString = [self substringToIndex:i];
CGSize stringSize = [testString sizeWithFont:font];
if (stringSize.height > rect.size.height || stringSize.width > rect.size.width)
break;
visibleString = testString;
}
return visibleString;
}
@end
Ответ 2
Здесь используется метод O (log n) с API iOS 7. Только поверхностно протестированные, прокомментируйте, если вы найдете какие-либо ошибки.
- (NSRange)hp_visibleRange
{
NSString *text = self.text;
NSRange visibleRange = NSMakeRange(NSNotFound, 0);
const NSInteger max = text.length - 1;
if (max >= 0)
{
NSInteger next = max;
const CGSize labelSize = self.bounds.size;
const CGSize maxSize = CGSizeMake(labelSize.width, CGFLOAT_MAX);
NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
paragraphStyle.lineBreakMode = self.lineBreakMode;
NSDictionary * attributes = @{NSFontAttributeName:self.font, NSParagraphStyleAttributeName:paragraphStyle};
NSInteger right;
NSInteger best = 0;
do
{
right = next;
NSRange range = NSMakeRange(0, right + 1);
NSString *substring = [text substringWithRange:range];
CGSize textSize = [substring boundingRectWithSize:maxSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:attributes
context:nil].size;
if (textSize.width <= labelSize.width && textSize.height <= labelSize.height)
{
visibleRange = range;
best = right;
next = right + (max - right) / 2;
} else if (right > 0)
{
next = right - (right - best) / 2;
}
} while (next != right);
}
return visibleRange;
}