Maison > Questions et réponses > le corps du texte
如题
比如
这个UIlabel 本该显示成
顶顶顶顶顶顶顶顶顶顶的大多数是是是是
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
谁谁谁水水水水是是是是是是是是是是撒
大多数是山东省撒打算打算打算打算的收
水电费第三方第三方说的发送到发送到范
水电费第三方士大夫士大夫。
但是 现在业务要求最多显示3行 如果小于3行有多少航显示多少行 超过三行的话显示如下
顶顶顶顶顶顶顶顶顶顶的大多数是是是是
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
谁谁谁水水水水是是是是是是是...展开
其中展开是蓝色 一点击...展开才变成
顶顶顶顶顶顶顶顶顶顶的大多数是是是是
顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶顶
谁谁谁水水水水是是是是是是是是是是撒
大多数是山东省撒打算打算打算打算的收
水电费第三方第三方说的发送到发送到范
水电费第三方士大夫士大夫。
我现在虽然到达了效果 但是方法比较复杂 且有时候还有问题 我想想问问大家 有没有什么好办法 好思路 最好有代码可以参考 谢谢了
天蓬老师2017-04-17 17:34:19
Il n'est pas pratique de limiter le nombre de caractères à l'étage. Les caractères chinois ont la même largeur, mais la largeur des autres caractères est incohérente, comme 1 et 8, un et 1, i et u, W et I.. .
Vous devez utiliser CoreText pour ce problème. Changez manuellement la composition, il y a cet AttributeLa en ligne. Bel, téléchargez d'abord le code et jetez-y un œil. Il est difficile de l'écrire entièrement à la main. Laissez-moi jeter un œil au code que nous avons téléchargé en ligne avant le projet et modifié par moi-même. Il a seulement ajouté... vous pouvez vous y référer, la méthode suivante est la méthode de l'étiquette personnalisée
- (void)drawTextInRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
//将当前context的坐标系进行flip,否则上下颠倒
CGAffineTransform flipVertical = CGAffineTransformMake(1,0,0,-1,0,self.bounds.size.height);
CGContextConcatCTM(context, flipVertical);
//设置字形变换矩阵为CGAffineTransformIdentity,也就是说每一个字形都不做图形变换
CGContextSetTextMatrix(context, CGAffineTransformIdentity);
NSString *attrStr = self.resultAttributedString.string;
NSRange range = NSMakeRange(0, attrStr.length);
NSDictionary *dic = [self.resultAttributedString attributesAtIndex:0 effectiveRange:&range];
NSMutableParagraphStyle *ps = [dic objectForKey:NSParagraphStyleAttributeName];
BOOL truncatTail = NO;
if(ps.lineBreakMode == NSLineBreakByTruncatingTail)
{
truncatTail = YES;
}
CTFramesetterRef framesetter = [self framesetter];
CGMutablePathRef pathRef = CGPathCreateMutable();
CGPathAddRect(pathRef,NULL , CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height));
_textFrame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, 0), pathRef,NULL );
NSInteger numberOfLines = [self numberOfDisplayedLines];
CGSize tempSize = self.frame.size;
CGSize trueSize = [self getLLLLabelSize];
if (_textFrame)
{
if (numberOfLines > 0 && tempSize.height < trueSize.height)
{
CFArrayRef lines = CTFrameGetLines(_textFrame);
CGPoint lineOrigins[numberOfLines];
CTFrameGetLineOrigins(_textFrame, CFRangeMake(0, numberOfLines), lineOrigins);
NSAttributedString *attributedString = self.resultAttributedString;
for (CFIndex lineIndex = 0; lineIndex < numberOfLines; lineIndex++)
{
CGPoint lineOrigin = lineOrigins[lineIndex];
CGContextSetTextPosition(context, lineOrigin.x, lineOrigin.y);
CTLineRef line = CFArrayGetValueAtIndex(lines, lineIndex);
BOOL shouldDrawLine = YES;
if (lineIndex == numberOfLines - 1 )
{
// Does the last line need truncation?
CFRange lastLineRange = CTLineGetStringRange(line);
if (lastLineRange.location + lastLineRange.length < attributedString.length)
{
CTLineTruncationType truncationType = kCTLineTruncationEnd;
//加省略号的位置
NSUInteger truncationAttributePosition = lastLineRange.location + lastLineRange.length - 1;
//获取省略号位置的字符串属性
NSDictionary *tokenAttributes = [attributedString attributesAtIndex:truncationAttributePosition
effectiveRange:NULL];
//初始化省略号的属性字符串
NSAttributedString *tokenString = [[NSAttributedString alloc] initWithString:kEllipsesCharacter
attributes:tokenAttributes];
//创建一行
CTLineRef truncationToken = CTLineCreateWithAttributedString((CFAttributedStringRef)tokenString);
NSMutableAttributedString *truncationString = [[attributedString attributedSubstringFromRange:NSMakeRange(lastLineRange.location, lastLineRange.length)] mutableCopy];
if (lastLineRange.length > 0)
{
// Remove last token
[truncationString deleteCharactersInRange:NSMakeRange(lastLineRange.length - 1, 1)];
}
[truncationString appendAttributedString:tokenString];
//创建省略号的行
CTLineRef truncationLine = CTLineCreateWithAttributedString((CFAttributedStringRef)truncationString);
// 在省略号行的末尾加上省略号
CTLineRef truncatedLine = CTLineCreateTruncatedLine(truncationLine, rect.size.width, truncationType, truncationToken);
if (!truncatedLine)
{
// If the line is not as wide as the truncationToken, truncatedLine is NULL
truncatedLine = CFRetain(truncationToken);
}
CFRelease(truncationLine);//CF得自己释放,ARC的不会释放
CFRelease(truncationToken);
CTLineDraw(truncatedLine, context);
CFRelease(truncatedLine);
shouldDrawLine = NO;
}
}
if(shouldDrawLine)
{
CTLineDraw(line, context);
}
}
}
else
{
CTFrameDraw(_textFrame,context);
}
}
CGContextRestoreGState(context);
}
ringa_lee2017-04-17 17:34:19
Cette exigence est en effet un peu difficile. Si c'était moi, je pourrais utiliser deux méthodes alternatives :
Au lieu de limiter à 3 lignes, limitez le nombre de mots à 3 lignes maximum, par exemple 50 mots, puis tronquez la chaîne, épelez "...", puis épelez "développer" et utilisez TTTAttributedlabel
Vous pouvez ajouter des événements de clic. Le nombre de mots peut également être déterminé individuellement en fonction de plusieurs largeurs d'écran.
Déplacez "Développer" en dehors de la plage de l'étiquette, limitez le nombre de lignes de l'étiquette à 3, puis "Développer" est un bouton séparé, placez-le à l'extérieur...
Si vous devez implémenter cela... La façon dont je peux penser est de scanner la chaîne du début à la fin dans une plage qui est probablement de 3 lignes, par exemple de 40 mots à 60 mots, d'abord la sous-chaîne puis de calculer BoundingRect hauteur jusqu'à ce que vous trouviez qu'il devient 4 lignes. Le texte précédent remplit exactement 3 lignes, coupez quelques mots supplémentaires, épelez "...", puis épelez "Développer". Mais la méthode de calcul deboundingRect est relativement lente, elle est donc définitivement très inefficace. Pas très recommandé.