Ich möchte die Anzahl der Zeilen und die Höhe des UILabels dynamisch aus dem gegebenen Text berechnen.
Antworten
Zu viele Anzeigen?Versuche dies
// UILabel *myLabel;
CGSize labelSize = [myLabel.text sizeWithFont:myLabel.font
constrainedToSize:myLabel.frame.size
lineBreakMode:NSLineBreakByWordWrapping];
CGFloat labelHeight = labelSize.height;
int lines = [myLabel.text sizeWithFont:myLabel.font
constrainedToSize:myLabel.frame.size
lineBreakMode:NSLineBreakByWordWrapping].height/16;
// '16' ist Schriftgröße
oder
int lines = labelHeight/16;
NSLog(@"Anzahl der Zeilen: %i \n\n",lines);
oder
int lines = [myLabel.text sizeWithFont:myLabel.font
constrainedToSize:myLabel.frame.size
lineBreakMode:UILineBreakModeWordWrap].height /myLabel.font.pointSize; //Schriftgröße aus der Schriftart abrufen
Durch die Verwendung von Kategorien, erstellen Sie die Kategorieklasse mit dem Namen
UILabel+UILabelDynamicHeight.h
UILabel+UILabelDynamicHeight.m
Keine Sorge mehr um die Höhenberechnung. Bitte überprüfen Sie die unten stehende Implementierung.
Aktualisierungen für iOS7 & höher, iOS 7 unten: Dynamische Berechnung der UILabel-Höhe
#define SYSTEM_VERSION_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedSame)
#define SYSTEM_VERSION_GREATER_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedDescending)
#define SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] == NSOrderedAscending)
#define SYSTEM_VERSION_LESS_THAN_OR_EQUAL_TO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedDescending)
#define iOS7_0 @"7.0"
UILabel+UILabelDynamicHeight.h
#import
@interface UILabel (UILabelDynamicHeight)
#pragma mark - Berechnen der Größe des mehrzeiligen Labels
/*====================================================================*/
/* Berechnen der Größe des mehrzeiligen Labels */
/*====================================================================*/
/**
* Gibt die Größe des Labels zurück
*
* @param aLabel Zur Berechnung der Höhe zu verwenden
*
* @return Größe des Labels
*/
-(CGSize)sizeOfMultiLineLabel;
@end
UILabel+UILabelDynamicHeight.m
#import "UILabel+UILabelDynamicHeight.h"
@implementation UILabel (UILabelDynamicHeight)
#pragma mark - Berechnen der Größe, Grenzen, Rahmen des mehrzeiligen Labels
/*====================================================================*/
/* Berechnen der Größe, der Grenzen, des Rahmens des mehrzeiligen Labels */
/*====================================================================*/
/**
* Gibt die Größe des Labels zurück
*
* @param aLabel Zur Berechnung der Höhe zu verwenden
*
* @return Größe des Labels
*/
-(CGSize)sizeOfMultiLineLabel{
//Label Text
NSString *aLabelTextString = [self text];
//Label Schriftart
UIFont *aLabelFont = [self font];
//Breite des Labels
CGFloat aLabelSizeWidth = self.frame.size.width;
if (SYSTEM_VERSION_LESS_THAN(iOS7_0)) {
//Version < 7.0
return [aLabelTextString sizeWithFont:aLabelFont
constrainedToSize:CGSizeMake(aLabelSizeWidth, MAXFLOAT)
lineBreakMode:NSLineBreakByWordWrapping];
}
else if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(iOS7_0)) {
//Version >= 7.0
//Gibt die berechnete Größe des Labels zurück
return [aLabelTextString boundingRectWithSize:CGSizeMake(aLabelSizeWidth, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{
NSFontAttributeName : aLabelFont
}
context:nil].size;
}
return [self bounds].size;
}
@end
Wenn Sie -sizeToFit
auf einer UILabel-Instanz aufrufen, wird sie automatisch auf die Größe des angezeigten Textes angepasst, ohne dass eine Berechnung erforderlich ist. Wenn Sie die Größe benötigen, können Sie sie nachher aus der frame-Eigenschaft des Labels erhalten.
label.numberOfLines = 0; // erlaubt dem Label, so viele Zeilen wie nötig zu haben
label.text = @"ein langer Text";
[label sizeToFit];
NSLog(@"Die Rahmen des Labels sind: %@", NSStringFromCGRect(label.frame));
Zusammenfassend lässt sich die Höhe eines Labels berechnen, indem man den String verwendet und boundingRectWithSize
aufruft. Sie müssen die Schriftart
als Attribut angeben und .usesLineFragmentOrigin
für mehrzeilige Labels hinzufügen.
let labelWidth = label.frame.width
let maxLabelSize = CGSize(width: labelWidth, height: CGFloat.greatestFiniteMagnitude)
let actualLabelSize = label.text!.boundingRect(with: maxLabelSize, options: [.usesLineFragmentOrigin], attributes: [.font: label.font], context: nil)
let labelHeight = actualLabelSize.height(withWidth:labelWidth)
Einige Erweiterungen, um genau das zu tun:
Swift-Version:
extension UILabel {
func textHeight(withWidth width: CGFloat) -> CGFloat {
guard let text = text else {
return 0
}
return text.height(withWidth: width, font: font)
}
func attributedTextHeight(withWidth width: CGFloat) -> CGFloat {
guard let attributedText = attributedText else {
return 0
}
return attributedText.height(withWidth: width)
}
}
extension String {
func height(withWidth width: CGFloat, font: UIFont) -> CGFloat {
let maxSize = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)
let actualSize = self.boundingRect(with: maxSize, options: [.usesLineFragmentOrigin], attributes: [.font : font], context: nil)
return actualSize.height
}
}
extension NSAttributedString {
func height(withWidth width: CGFloat) -> CGFloat {
let maxSize = CGSize(width: width, height: CGFloat.greatestFiniteMagnitude)
let actualSize = boundingRect(with: maxSize, options: [.usesLineFragmentOrigin], context: nil)
return actualSize.height
}
}
Objective-C-Version:
UILabel+Utility.h
#import
@interface UILabel (Utility)
- (CGFloat)textHeightForWidth:(CGFloat)width;
- (CGFloat)attributedTextHeightForWidth:(CGFloat)width;
@end
UILabel+Utility.m
@implementation NSString (Utility)
- (CGFloat)heightForWidth:(CGFloat)width font:(UIFont *)font {
CGSize maxSize = CGSizeMake(width, CGFLOAT_MAX);
CGSize actualSize = [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : font} context:nil].size;
return actualSize.height;
}
@end
@implementation NSAttributedString (Utility)
- (CGFloat)heightForWidth:(CGFloat)width {
CGSize maxSize = CGSizeMake(width, CGFLOAT_MAX);
CGSize actualSize = [self boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin context:nil].size;
return actualSize.height;
}
@end
@implementation UILabel (Utility)
- (CGFloat)textHeightForWidth:(CGFloat)width {
return [self.text heightForWidth:width font:self.font];
}
- (CGFloat)attributedTextHeightForWidth:(CGFloat)width {
return [self.attributedText heightForWidth:width];
}
@end
Die aktuelle Lösung wurde ab iOS 7 verworfen.
Hier ist eine aktualisierte Lösung:
+ (CGFloat)heightOfCellWithIngredientLine:(NSString *)ingredientLine
withSuperviewWidth:(CGFloat)superviewWidth
{
CGFloat labelWidth = superviewWidth - 30.0f;
// Verwenden Sie die bekannte Label-Breite mit einer maximalen Höhe von 100 Punkten
CGSize labelContraints = CGSizeMake(labelWidth, 100.0f);
NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
CGRect labelRect = [ingredientLine boundingRectWithSize:labelContraints
options:NSStringDrawingUsesLineFragmentOrigin
attributes:nil
context:context];
// Geben Sie die berechnete erforderliche Höhe der Zelle unter Berücksichtigung des Labels zurück
return labelRect.size.height;
}
Der Grund, warum meine Lösung so eingerichtet ist, liegt darin, dass ich eine UITableViewCell verwende und die Zelle dynamisch entsprechend dem Platzbedarf des Labels anpassen möchte.
Ohne sizeToFit aufzurufen, können Sie dies alles numerisch mit einer sehr einfachen Lösung machen:
+ (CGFloat)heightForText:(NSString*)text font:(UIFont*)font withinWidth:(CGFloat)width {
CGSize size = [text sizeWithAttributes:@{NSFontAttributeName:font}];
CGFloat area = size.height * size.width;
CGFloat height = roundf(area / width);
return ceilf(height / font.lineHeight) * font.lineHeight;
}
Ich benutze es oft für UITableViewCells, die dynamisch zugewiesene Höhen haben.
Löst auch das Problem der Attribute, @Salman Zaidi.
- See previous answers
- Weitere Antworten anzeigen