Wyświetlałem tekst w UILabel za pomocą metody wrap. Teraz chcę znaleźć numer linii w UILabel.Jak znaleźć liczbę linii UILabel
Jeśli istnieje jakikolwiek sposób na znalezienie liczby wierszy UILabel.
Dzięki.
Wyświetlałem tekst w UILabel za pomocą metody wrap. Teraz chcę znaleźć numer linii w UILabel.Jak znaleźć liczbę linii UILabel
Jeśli istnieje jakikolwiek sposób na znalezienie liczby wierszy UILabel.
Dzięki.
Jak wskazano, ten post dotyczy sposobu uzyskania wysokości, a nie liczby linii. Aby uzyskać liczbę linii, należy uzyskać wysokość pojedynczej litery, np.
@"A"
.E.g.
CGFloat unitHeight = [@"A" heightForWidth:width usingFont:font];
CGFloat blockHeight = [text heightForWidth:width usingFont:font];
NSInteger numberOfLines = ceilf(blockHeight/unitHeight);
// need to #include <math.h> for ^^^^^
Jako iOS 7 drodze uzyskanie etykiety pożądaną wysokość zmieniło. Aby uzyskać wysokość, można użyć następującego kodu:
gdzie wysokość jest r.size.height
. Należy podać font
. Możesz umieścić to w kategorii dla NSString dla wygody, np.
@implementation NSString (HeightCalc)
- (CGFloat)heightForWidth:(CGFloat)width usingFont:(UIFont *)font
{
NSStringDrawingContext *context = [[NSStringDrawingContext alloc] init];
CGSize labelSize = (CGSize){width, FLT_MAX};
CGRect r = [self boundingRectWithSize:labelSize options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName: font} context:context];
return r.size.height;
}
@end
(Czy zarządzanie pamięcią, jeśli nie za pomocą łuku, btw.)
Dla iOS 6 i poniżej:
Powiedzmy masz UILabel *myLabel
i chcesz dowiedzieć się wysokość etykieta (z pewnymi poprawkami, możesz uzyskać # linii dzieląc wysokość z odpowiednią liczbą, która zależy od rozmiaru czcionki).
UILabel *myLabel;
CGSize labelSize = [myLabel.text sizeWithFont:myLabel.font
constrainedToSize:myLabel.frame.size
lineBreakMode:UILineBreakModeWordWrap];
CGFloat labelHeight = labelSize.height;
Nadzieję, że pomaga. Jeśli to nie zadziała, daj mi znać, a przekopię się dalej. Również nietestowany kod, ale działał z referencji.
Pełniejszy przykład, tutaj jest kod, który umieścić w viewDidLoad: metoda kontrolera widoku:
[super viewDidLoad];
UILabel *myLabel = [[UILabel alloc] initWithFrame:CGRectMake(50,50,200,350)];
myLabel.numberOfLines = 0;
myLabel.lineBreakMode = UILineBreakModeWordWrap;
myLabel.text = @"This is some text in a UILabel which is long enough to wrap around the lines in said UILabel. This is a test, this is only a test.";
[self.view addSubview:myLabel];
CGSize labelSize = [myLabel.text sizeWithFont:myLabel.font
constrainedToSize:myLabel.frame.size
lineBreakMode:UILineBreakModeWordWrap];
CGFloat labelHeight = labelSize.height;
NSLog(@"labelHeight = %f", labelHeight);
[myLabel release];
Wyjście z NSLog idzie:
2010-11-15 18:25:27.817 so_labelheight[728:307] labelHeight = 126.000000
pokazuje następujące dwa błędy // błąd: niekompatybilny typ dla argumentu 2 z "sizeWithFont: constrainedToSize : lineBreakMode:” \t \t \t błąd: żądanie członka«rozmiar»w coś nie struktury lub unii – Velmurugan
Oczywiście .size nie jest właściwością na UILabel, ale powinno to prawdopodobnie coś myLabel.frame.size lub myLabel .bounds.size (nie wiesz, który z nich chcesz). –
Ach tak, tęskniłem za tym. Dzięki Wim H. Naprawiono powyższy przykład, aby użyć frame.size. – Kalle
Sposób -sizeWithFont:constrainedToSize:lineBreakMode
jest teraz przestarzałe. Będziesz teraz chciał użyć metody -boundingRectWithSize:options:attributes:context:
.
Oto przykłady:
CGSize boundingRectSize = CGSizeMake(widthToConstrainTo, CGFLOAT_MAX);
NSDictionary *attributes = @{NSFontAttributeName : [UIFont fontWithName:fontName size:14]};
CGRect labelSize = [labelString boundingRectWithSize:boundingRectSize options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading
attributes:attributes
context:nil];
W powyższym przykładzie wiem szerokość Chcę ograniczyć etykietę, ale ponieważ nie jestem pewien co do wysokości, po prostu max wysokość param z wykorzystaniem CGFLOAT_MAX
. W przypadku modelu options
należy użyć wartości NSStringDrawingUsesLineFragmentOrigin
i NSStringDrawingUsesFontLeading
, jeśli próbujesz obliczyć rozmiar etykiety, która może być dowolną liczbą linii.
sizeWithFont
jest przestarzałe w iOS 7, można użyć zamiast tego:
- (int)lineCountForText:(NSString *) text
{
UIFont *font = ...
CGRect rect = [text boundingRectWithSize:CGSizeMake(200, MAXFLOAT)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName : font}
context:nil];
return ceil(rect.size.height/font.lineHeight);
}
Dla iOS7 i powyżej, officially sanctioned way policzyć liczbę linii jest użycie TextKit:
func numberOfLinesForString(string: String, size: CGSize, font: UIFont) -> Int {
let textStorage = NSTextStorage(string: string, attributes: [NSFontAttributeName: font])
let textContainer = NSTextContainer(size: size)
textContainer.lineBreakMode = .ByWordWrapping
textContainer.maximumNumberOfLines = 0
textContainer.lineFragmentPadding = 0
let layoutManager = NSLayoutManager()
layoutManager.textStorage = textStorage
layoutManager.addTextContainer(textContainer)
var numberOfLines = 0
var index = 0
var lineRange : NSRange = NSMakeRange(0, 0)
for (; index < layoutManager.numberOfGlyphs; numberOfLines++) {
layoutManager.lineFragmentRectForGlyphAtIndex(index, effectiveRange: &lineRange)
index = NSMaxRange(lineRange)
}
return numberOfLines
}
(Pierwotnie opublikowałem moją odpowiedź: here, ale nie mam wystarczającej reputacji, aby komentować lub oznaczać duplikaty.)
Pozostałe odpowiedzi I'v e znalezione nie szanują własność UILabel
numberOfLines
gdy jest on ustawiony na wartość inną niż 0.
Oto kolejny opcji można dodać do danej kategorii lub podklasy:
- (NSUInteger)lineCount
{
CGSize size = [self sizeThatFits:CGSizeMake(self.frame.size.width, CGFLOAT_MAX)];
return MAX((int)(size.height/self.font.lineHeight), 0);
}
Kilka uwag:
font
i działa poprawnie. Oczywiście natknąłbyś się na problemy, gdybyś używał wielu czcionek w swoim attributedText
.UILabel
mieć wypustki zwyczaj krawędź (na przykład poprzez nadpisanie drawTextInRect:
, co jest miłe sztuczka znalazłem here), trzeba pamiętać, aby wziąć pod uwagę te wypustki przy obliczaniu size
powyżej. Na przykład: CGSizeMake(self.frame.size.width - (self.insets.left + self.insets.right), CGFLOAT_MAX)
Jeśli szukasz tej odpowiedzi w Swift 2 +/iOS 8, to będzie wyglądać następująco:
func numberOfLinesInLabel(yourString: String, labelWidth: CGFloat, labelHeight: CGFloat, font: UIFont) -> Int {
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.minimumLineHeight = labelHeight
paragraphStyle.maximumLineHeight = labelHeight
paragraphStyle.lineBreakMode = .ByWordWrapping
let attributes: [String: AnyObject] = [NSFontAttributeName: font, NSParagraphStyleAttributeName: paragraphStyle]
let constrain = CGSizeMake(labelWidth, CGFloat(Float.infinity))
let size = yourString.sizeWithAttributes(attributes)
let stringWidth = size.width
let numberOfLines = ceil(Double(stringWidth/constrain.width))
return Int(numberOfLines)
}
Ta odpowiedź jest dobra od iOS8 –
Dzięki @AvielGross. Edytowane w celu odzwierciedlenia danych wejściowych. – cph2117
Jaki jest cel "ograniczenia" tutaj? –
func getHeight(text: NSString, width:CGFloat, font: UIFont) -> CGFloat
{
let rect = text.boundingRect(with: CGSize.init(width: width, height: CGFloat.greatestFiniteMagnitude), options: ([NSStringDrawingOptions.usesLineFragmentOrigin,NSStringDrawingOptions.usesFontLeading]), attributes: [NSFontAttributeName:font], context: nil)
return rect.size.height
}
tekst: Etykieta którego wysokość trzeba znaleźć z danym ciągiem
width: szerokość UILabel
czcionki: czcionka UILabel za
http://stackoverflow.com/questions/4082041/resulting-lines-of-uilabel-with-uilinebreakmodewordwrap/14401282#14401282 – TheTiger