Je dois calculer le texte rect dans mon étiquette personnalisée sans utiliser la méthode sizeThatFits de UILabel. Le code ci-dessous ne fonctionne pas correctement. L'idée principale est de trouver CTLine à index = numberOfLines - 1 et de renvoyer sa position max y. Mais en conséquence, la hauteur du texte est parfois trop grande et parfois insuffisante pour dessiner la dernière ligne.NSAttributedString height limité par width et numberOfLines
- (CGSize)fittingSizeWithSize:(CGSize)size numberOfLines:(NSInteger)numberOfLines {
if (numberOfLines == 0) {
return [self fittingSizeWithSize:size];
}
CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)self);
if (framesetter == NULL) {
return CGSizeZero;
}
CGPathRef path = CGPathCreateWithRect(CGRectMake(0,0,size.width,size.height), NULL);
CTFrameRef frame = CTFramesetterCreateFrame(framesetter, CFRangeMake(0, self.length), path, NULL);
NSArray *lines = (NSArray *) CTFrameGetLines(frame);
if (lines.count == 0) {
return CGSizeZero;
}
NSUInteger lineIndex = MIN((NSUInteger)numberOfLines, lines.count) - 1;
CTLineRef line = (__bridge CTLineRef) lines[lineIndex];
CGPoint origins[[lines count]];
CTFrameGetLineOrigins(frame, CFRangeMake(0, 0), origins);
CGAffineTransform transform = CGAffineTransformMakeTranslation(0, size.height);
transform = CGAffineTransformScale(transform, 1, -1);
CGRect lineRect;
CGFloat ascent;
CGFloat descent;
lineRect.size.width = (CGFloat)CTLineGetTypographicBounds(line, &ascent, &descent, NULL); //8
lineRect.size.height = ascent + descent;
lineRect.origin.y = CGPointApplyAffineTransform(origins[lineIndex], transform).y;
CGFloat height = CGRectGetMaxY(lineRect);
CFRelease(path);
CFRelease(framesetter);
return CGSizeMake(size.width, height);
}
Cette catégorie de NSAttributedString utilisé dans ma sous-classe UILabel
@implementation SMBDLabel
- (void)drawTextInRect:(CGRect)rect {
if (self.attributedText) {
CGContextRef ctx = UIGraphicsGetCurrentContext();
[self.attributedText drawInContext:ctx viewBounds:rect];
} else {
[super drawTextInRect:rect];
}
}
- (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines {
CGSize size = [self.attributedText fittingSizeWithSize:bounds.size numberOfLines:numberOfLines];
return CGRectMake(0, 0, size.width, size.height);
}
- (CGSize)sizeThatFits:(CGSize)size {
return [self.attributedText fittingSizeWithSize:size numberOfLines:self.numberOfLines];
}
@end
Je ne sais pas où mon erreur. Peut-être même erreur dans la sous-classe UILabel
Pourquoi utiliser un texte de base, lorsque NSAttributedString a déjà 'boundingRectWithSize: Options: contexte:'? – matt
Aussi bien que je ne peux pas utiliser NSTextAttachment (il y a un bug avec le retour à la ligne et aucune solution de contournement utilisable), je dessine mes pièces jointes d'image personnalisée. Il y a aussi un problème avec le remplacement de UILabel par des sous-classes de UIView. – Arsynth
Je ne suis pas de tout ça. Vous avez Text Kit maintenant. Vous ne devriez pas avoir besoin de Core Text pour quoi que ce soit. Et UITextView vous permet d'utiliser directement Text Kit, en plus il peut simuler le comportement de UILabel. – matt