Porównaj ceny domen i usług IT, sprzedawców z całego świata

Obliczanie rozmiaru tekstu UILabel


Rysuję
UILabels
programowo. Pobierają swoje rozmiary z bazy danych. Więc nie mogę po prostu użyć
sizeToFit
. Zaimplementowałem już funkcję, która przerysowuje
UILabels
z podanym współczynnikiem. Więc wszystko, co potrzebuję, to tekst w
UILabel
z mojego punktu widzenia, co wymagałoby maksymalnego współczynnika do ponownego narysowania
UILabels
.
W końcu muszę zrobić coś takiego:
double ratio = 1.00;
for (UILabel* labels in sec.subviews) { float widthLabel = labels.frame.size.width;
float heightLabel = labels.frame.size.height;
float heightText =//get the text height here
float widthText =//get the text width here
if (widthLabel < widthText) {
ratio = MAX(widthText/widthLabel,ratio);
}
if (heightLabel < heightText) {
ratio = MAX(heightText/heightLabel, ratio);
}
}
//redraw UILabels with the given ratio here

Jak więc mogę uzyskać rozmiar wysokości i szerokości tekstu, skoro niektóre z moich tekstów nie mieszczą się na etykiecie, nie mogę po prostu użyć krawędzi etykiety? Używam Xcode 5 i iOS 7.
Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Wszystkie metody
[NSString sizeWithFont ...]
są przestarzałe w iOS 7. Zamiast tego użyj tego.
CGRect labelRect = [text
boundingRectWithSize:labelSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{
NSFontAttributeName : [UIFont systemFontOfSize:14]
}
context:nil];

Widzieć

Zobacz też https://developer.apple.com/do ... hfont
https://developer.apple.com/do ... hfont
.

UPDATE przykład wyjścia boundingRectWithSize
>
Zgodnie z twoim komentarzem wykonałem prosty test. Kod i dane wyjściowe przedstawiono poniżej.
// code to generate a bounding rect for text at various font sizes
NSString *text = @"This is a long sentence. Wonder how much space is needed?";
for (NSNumber *n in @[@(12.0f), @(14.0f), @(18.0f)]) {
CGFloat fontSize = [n floatValue];
CGRect r = [text boundingRectWithSize:CGSizeMake(200, 0)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]}
context:nil];
NSLog(@"fontSize = %f\tbounds = (%f x %f)",
fontSize,
r.size.width,
r.size.height);
}

daje to następujący wynik (zauważ, że obramowania zmieniają się zgodnie z oczekiwaniami wraz ze wzrostem rozmiaru czcionki):
fontSize = 12.000000 bounds = (181.152008 x 28.632000)
fontSize = 14.000000 bounds = (182.251999 x 50.105999)
fontSize = 18.000000 bounds = (194.039993 x 64.421997)
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Długość otrzymuje liczbę znaków. Jeśli chcesz uzyskać szerokość tekstu:

Objective-C

CGSize textSize = [label.text sizeWithAttributes:@{NSFontAttributeName:[label font]}];


Swift 4

let size = label.text?.size(withAttributes: [.font: label.font]) ?? .zero

To daje rozmiar. Możesz też porównać
textSize.width
każdej etykiety.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Inny łatwy sposób na zrobienie tego, o którym jeszcze nie wspomniałem:
CGSize textSize = [label intrinsicContentSize];

(Oczywiście działa to poprawnie tylko po ustawieniu tekstu i czcionki etykiety).
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Oto szybki wariant.
let font = UIFont(name: "HelveticaNeue", size: 25)!
let text = "This is some really long text just to test how it works for calculating heights in swift of string sizes. What if I add a couple lines of text?"let textString = text as NSStringlet textAttributes = [NSFontAttributeName: font]textString.boundingRectWithSize(CGSizeMake(320, 2000), options: .UsesLineFragmentOrigin, attributes: textAttributes, context: nil)
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Mała rada, jeśli mnie lubisz, używaj
boundingRectWithSize
z
[UIFont systemFontOFSize: 14]
Jeśli twój ciąg ma dwie linie, zwrócona wysokość prostownika wynosi około 33,4 punktu.
Nie popełnij błędu tak jak ja, rzucając go na
int
, ponieważ 33,4 staje się 33, a 33 punkty wysokości etykiety idą z dwóch do jednej linii!
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Problem z
CGRect r = [text boundingRectWithSize:CGSizeMake(200, 0)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]}
context:nil];

jest to
boundingRectWithSize
, które definiuje maksymalną wartość, jaką może mieć CGRect.
Moim rozwiązaniem tego problemu jest sprawdzenie, czy przekracza, jeśli nie, to tekst zmieści się na etykiecie. Zrobiłem to z pętlami.
NSString *text = @"This is a long sentence. Wonder how much space is needed?";
CGFloat width = 100;
CGFloat height = 100;
bool sizeFound = false;
while (!sizeFound) {
NSLog(@"Begin loop");
CGFloat fontSize = 14;
CGFloat previousSize = 0.0;
CGFloat currSize = 0.0;
for (float fSize = fontSize; fSize < fontSize+6; fSize++) {
CGRect r = [text boundingRectWithSize:CGSizeMake(width, height)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fSize]}
context:nil];
currSize =r.size.width*r.size.height;
if (previousSize >= currSize) {
width = width*11/10;
height = height*11/10;
fSize = fontSize+10;
}
else {
previousSize = currSize;
}
NSLog(@"fontSize = %f\tbounds = (%f x %f) = %f",
fSize,
r.size.width,
r.size.height,r.size.width*r.size.height);
}
if (previousSize == currSize) {
sizeFound = true;
}}
NSLog(@"Size found with width %f and height %f", width, height);

Po każdej iteracji rozmiar wysokości i szerokości zwiększa się o 10% ich wartości.
Powodem, dla którego wybrałem 6 jest to, że nie chciałem, aby etykieta była zbyt miękka.
W przypadku rozwiązania, które nie używa pętli:
NSString *text = @"This is a long sentence. Wonder how much space is needed?";
CGFloat width = 100;
CGFloat height = 100;CGFloat currentFontSize = 12;
CGRect r1 = [text boundingRectWithSize:CGSizeMake(width, height)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:currentFontSize+6]}
context:nil];CGRect r2 = [text boundingRectWithSize:CGSizeMake(width, height)
options:NSStringDrawingUsesFontLeading
attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:currentFontSize+6]}
context:nil];CGFloat firstVal =r1.size.width*r1.size.height;
CGFloat secondVal =r2.size.width*r2.size.height;NSLog(@"First val %f and second val is %f", firstVal, secondVal);if (secondVal > firstVal) {
float initRat = secondVal/firstVal; float ratioToBeMult = sqrtf(initRat); width *= ratioToBeMu<
height *= ratioToBeMu<
}NSLog(@"Final width %f and height %f", width, height);//for verifying
for (NSNumber *n in @[@(12.0f), @(14.0f), @(17.0f)]) {
CGFloat fontSize = [n floatValue];
CGRect r = [text boundingRectWithSize:CGSizeMake(width, height)
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:fontSize]}
context:nil];
NSLog(@"fontSize = %f\tbounds = (%f x %f) = %f",
fontSize,
r.size.width,
r.size.height,r.size.width*r.size.height);
firstVal =r.size.width*r.size.height;
}

Gdzie ostatnia pętla jest dowodem na to, że większa czcionka może dać wynik o większym rozmiarze.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Rozwiązanie, które działa z etykietami wielowierszowymi (Swift 4) Aby obliczyć wysokość przy stałej szerokości:
<pre class="lang-swift prettyprint-override">
let label = UILabel(frame: .zero)
label.numberOfLines = 0// multiline
label.font = UIFont.systemFont(ofSize: UIFont.labelFontSize)// your font
label.preferredMaxLayoutWidth = width// max width
label.text = "This is a sample text.\nWith a second line!"// the text to display in the labellet height = label.intrinsicContentSize.height
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Korzystając z tej linii kodu, możemy uzyskać rozmiar tekstu na etykiecie.
let str = "Sample text"
let size = str.sizeWithAttributes([NSFontAttributeName:UIFont.systemFontOfSize(17.0)])

W ten sposób możemy użyć zarówno szerokości, jak i wysokości.
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Ciąg msgStr otrzymuje rozmiar:
let msgStr:NSString = Data["msg"]! as NSString
let messageSize = msgStr.boundingRect(with: CGSize(width: ChatTable.frame.width-116, height: CGFloat.infinity), options: .usesLineFragmentOrigin, attributes: [NSFontAttributeName:UIFont(name: "Montserrat-Light", size: 14)!], context: nil).size
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:


Swift 3.0

func getLabelHeight() -> CGFloat {
let font = UIFont(name: "OpenSans", size: 15)!
let textString = "Lorem ipsum dolor sit er elit lamet, consectetaur cillium adipisicing pecu, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua." as NSString let textAttributes = [NSFontAttributeName: font] let rect = textString.boundingRect(with: CGSize(width: 320, height: 2000), options: .usesLineFragmentOrigin, attributes: textAttributes, context: nil)
return rect.size.height
}

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się