Oto mój działający fragment kodu:
NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithDictionary:attributeDict];
NSString *headline = [dict objectForKey:@"title"];
UIFont *font = [UIFont boldSystemFontOfSize:18];
CGRect rect = [headline boundingRectWithSize:CGSizeMake(300, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
CGFloat height = roundf(rect.size.height +4)
Dodałem 4px do wyliczonej wysokości, bo bez tych 4px brakuje jednej linii.
Używam tego fragmentu kodu w tableView i dodaję „wysokość” do tablicy NSNumbers i otrzymuję poprawną wysokość komórki dla domyślnego textLabel.
Dodaj 4 więcej pikseli, jeśli chcesz mieć więcej miejsca pod tekstem w textLabel.
**** AKTUALIZACJA ****
Nie zgadzam się z „błędem szerokości 40px”, krzyczę jako 4px brakującej wysokości, ponieważ 4px to domyślna wysokość odstępu między literą a granicą jednej linii. Możesz to sprawdzić za pomocą UILabel, dla rozmiaru czcionki 16 potrzebujesz UILabel wysokości 20.
Ale jeśli ostatnia linia nie zawiera „g” lub czegokolwiek innego, pomiar może nie mieć 4 piks. Wysokości.
Ponownie sprawdziłem to małą metodą, otrzymałem dokładną wysokość 20,40 lub 60 dla mojej etykiety i odpowiednią szerokość mniejszą niż 300 pikseli.
Aby obsługiwać iOS6 i iOS7, możesz użyć mojej metody:
- (CGFloat)heightFromString:(NSString*)text withFont:(UIFont*)font constraintToWidth:(CGFloat)width
{
CGRect rect;
float iosVersion = [[[UIDevice currentDevice] systemVersion] floatValue];
if (iosVersion >= 7.0) {
rect = [text boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
}
else {
CGSize size = [text sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
rect = CGRectMake(0, 0, size.width, size.height);
}
NSLog(@"%@: W: %.f, H: %.f", self, rect.size.width, rect.size.height);
return rect.size.height;
}
**** AKTUALIZACJA ****
Dzięki waszym komentarzom zaktualizowałem moją funkcję w następujący sposób. Ponieważ sizeWithFont jest przestarzałe i otrzymasz ostrzeżenie w XCode, dodałem diagnostyczny kod pragma, aby usunąć ostrzeżenie dla tego konkretnego wywołania funkcji / bloku kodu.
- (CGFloat)heightFromStringWithFont:(UIFont*)font constraintToWidth:(CGFloat)width
{
CGRect rect;
if ([self respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) {
rect = [self boundingRectWithSize:CGSizeMake(width, 1000) options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:font} context:nil];
}
else {
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
CGSize size = [self sizeWithFont:font constrainedToSize:CGSizeMake(width, 1000) lineBreakMode:NSLineBreakByWordWrapping];
rect = CGRectMake(0, 0, size.width, size.height);
#pragma GCC diagnostic pop
}
return ceil(rect.size.height);
}
Oprócz tematu 4px: w zależności od używanej czcionki i grubości czcionki obliczenie zwraca różne wartości wysokości. W moim przypadku: HelveticaNeue-Medium z rozmiarem czcionki 16,0 zwraca wysokość linii 20,0 dla jednego wiersza, ale 39,0 dla dwóch wierszy, 78 pikseli dla 4 wierszy -> brak 1 piksela dla każdego wiersza - zaczynając od wiersza 2 - ale chcesz aby mieć rozmiar czcionki + 4 piksele odstępów między wierszami dla każdej linii, musisz otrzymać wynik wysokości.
Pamiętaj o tym podczas kodowania!
Nie mam jeszcze funkcji dla tego "problemu", ale zaktualizuję ten post, kiedy skończę.