Czy można używać właściwości automatycznego tłumienia w połączeniu z wieloma liniami na UILabel
? na przykład duży rozmiar tekstu możliwy na 2 dostępnych liniach.Autoskórowanie na UILabel z wieloma liniami
Odpowiedz
Ci ludzie znaleźli rozwiązanie:
http://www.11pixel.com/blog/28/resize-multi-line-text-to-fit-uilabel-on-iphone/
Ich rozwiązanie jest następujące:
int maxDesiredFontSize = 28;
int minFontSize = 10;
CGFloat labelWidth = 260.0f;
CGFloat labelRequiredHeight = 180.0f;
//Create a string with the text we want to display.
self.ourText = @"This is your variable-length string. Assign it any way you want!";
/* This is where we define the ideal font that the Label wants to use.
Use the font you want to use and the largest font size you want to use. */
UIFont *font = [UIFont fontWithName:@"Marker Felt" size:maxDesiredFontSize];
int i;
/* Time to calculate the needed font size.
This for loop starts at the largest font size, and decreases by two point sizes (i=i-2)
Until it either hits a size that will fit or hits the minimum size we want to allow (i > 10) */
for(i = maxDesiredFontSize; i > minFontSize; i=i-2)
{
// Set the new font size.
font = [font fontWithSize:i];
// You can log the size you're trying: NSLog(@"Trying size: %u", i);
/* This step is important: We make a constraint box
using only the fixed WIDTH of the UILabel. The height will
be checked later. */
CGSize constraintSize = CGSizeMake(labelWidth, MAXFLOAT);
// This step checks how tall the label would be with the desired font.
CGSize labelSize = [self.ourText sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
/* Here is where you use the height requirement!
Set the value in the if statement to the height of your UILabel
If the label fits into your required height, it will break the loop
and use that font size. */
if(labelSize.height <= labelRequiredHeight)
break;
}
// You can see what size the function is using by outputting: NSLog(@"Best size is: %u", i);
// Set the UILabel's font to the newly adjusted font.
msg.font = font;
// Put the text into the UILabel outlet variable.
msg.text = self.ourText;
W celu uzyskania tej pracy, o IBOutlet musi być przypisany w konstruktora interfejsu do UILabel.
"IBOutlet UILabel * msg;"
Wszystko jest zasługą ludzi w 11pixel.
I zmodyfikowany powyższy kod nieco aby to kategoria na UILabel
: file
Header:
#import <UIKit/UIKit.h>
@interface UILabel (MultiLineAutoSize)
- (void)adjustFontSizeToFit;
@end
a plik realizacja:
@implementation UILabel (MultiLineAutoSize)
- (void)adjustFontSizeToFit
{
UIFont *font = self.font;
CGSize size = self.frame.size;
for (CGFloat maxSize = self.font.pointSize; maxSize >= self.minimumFontSize; maxSize -= 1.f)
{
font = [font fontWithSize:maxSize];
CGSize constraintSize = CGSizeMake(size.width, MAXFLOAT);
CGSize labelSize = [self.text sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:UILineBreakModeWordWrap];
if(labelSize.height <= size.height)
{
self.font = font;
[self setNeedsLayout];
break;
}
}
// set the font to the minimum size anyway
self.font = font;
[self setNeedsLayout];
}
@end
Wspaniale, potknąłem się o to samo i to rozwiązuje w mgnieniu oka :-) Tylko dwie uwagi: ** (1) ** pierwsze dwie linie w wewnętrznej klauzuli "jeśli" są zbędne, ponieważ będą wykonywane tuż pod cyklem "za". ** (2) ** jeśli istnieje potrzeba, aby tekst UILabel był pionowo wyrównany do góry (w przypadku, gdy używa on mniej linii niż faktycznie może być pokazany na etykiecie), wystarczy ustawić wysokość etykiety na labelSize.height. Zauważ, że sizeToFit nie może być użyte do tego celu, ponieważ łamie wcześniej sformatowany tekst i dopasowuje go do oryginalnego rozmiaru czcionki. – FurloSK
To jest idealne, ale metoda minimalnaFontSize jest przestarzała w systemie iOS6 - jak można to zmienić, aby działała z minimalnym współczynnikiem skali? – bmueller
Właśnie tego potrzebowałem. Dzięki. +1 –
Podobało mi odpowiedź DaGaMs, ale w używaniu etykiet, takich jak w komórkach UITableViewCell, które mogą być zwrócone przez dequeueReusableCell :, zwykły rozmiar czcionki będzie się zmniejszał nawet w rozmiarze oryginalnym było nadal pożądane w przypadku niektórych komórek tableView, które zawierały mniej tekstu i mogły korzystać z oryginalnego rozmiaru czcionki oryginalnej etykiety.
Więc zaczynając kategorii DaGaMs jako baza wypadowa, i stworzył oddzielną klasę zamiast odrębną kategorię, i upewnić się, moje UILabels w moim serii ujęć skorzystać z tej nowej klasy:
#import "MultiLineAutoShrinkLabel.h"
@interface MultiLineAutoShrinkLabel()
@property (readonly, nonatomic) UIFont* originalFont;
@end
@implementation MultiLineAutoShrinkLabel
@synthesize originalFont = _originalFont;
- (UIFont*)originalFont { return _originalFont ? _originalFont : (_originalFont = self.font); }
- (void)quoteAutoshrinkUnquote
{
UIFont* font = self.originalFont;
CGSize frameSize = self.frame.size;
CGFloat testFontSize = _originalFont.pointSize;
for (; testFontSize >= self.minimumFontSize; testFontSize -= 0.5)
{
CGSize constraintSize = CGSizeMake(frameSize.width, MAXFLOAT);
CGSize testFrameSize = [self.text sizeWithFont:(font = [font fontWithSize:testFontSize])
constrainedToSize:constraintSize
lineBreakMode:self.lineBreakMode];
// the ratio of testFontSize to original font-size sort of accounts for number of lines
if (testFrameSize.height <= frameSize.height * (testFontSize/_originalFont.pointSize))
break;
}
self.font = font;
[self setNeedsLayout];
}
@end
+1 za radzenie sobie z UITableViewCells. Ale gdzie jest kod dla twojego interfejsu MultilineAutoShrinkLabel.h? – Rhubarb
@Rhubarb, to po prostu trywialne: podklasa UILabel z jedną funkcją, '- (void) quoteAutoshrinkUnquote;' ... i faktycznie, przeszedłem do użycia czegoś podobnego, ale nieco bardziej skomplikowanego, co dotyczy akcesorium po prawej stronie oraz fakt, że może to być 2 różne rozmiary, pozwalające na mniej lub bardziej ekranową nieruchomość na komórkę. –
Użyłem tej odpowiedzi, aby odpowiedzieć na moją własną wersję, a także zaktualizowałem kod, aby usunąć nieaktualne metody. Http://stackoverflow.com/a/30898604/758083 – Hackmodford
Dziękuję DaGaM za to rozwiązanie.
zaktualizowałem go w następujący sposób:
1 - Aby pracować z iOS 6 (ponieważ oba minimumFontSize i UILineBreakModeWordWrap są przestarzałe) 2 - Aby rozebrać spacje z tekstu etykiety, ponieważ spowoduje to zmianę rozmiaru do fail (nie chcesz wiedzieć, jak długo zajęło mi znaleźć ten błąd) odpowiedź
-(void)adjustFontSizeToFit
{
self.text = [self.text stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
UIFont *font = self.font;
CGSize size = self.frame.size;
for (CGFloat maxSize = self.font.pointSize; maxSize >= self.minimumScaleFactor; maxSize -= 1.f)
{
font = [font fontWithSize:maxSize];
CGSize constraintSize = CGSizeMake(size.width, MAXFLOAT);
CGSize labelSize = [self.text sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
if(labelSize.height <= size.height)
{
self.font = font;
[self setNeedsLayout];
break;
}
}
// set the font to the minimum size anyway
self.font = font;
[self setNeedsLayout];
}
'minimumScaleFactor' ma wartość dziesiętną, np. 0,2. 'maxSize> = self.minimumScaleFactor' zmniejszy rozmiar do 0.2. Zamiast tego nie chcesz "maxSize> = self.minimumScaleFactor * self.font.pointSize" lub coś podobnego? – pwightman
itedcedor zawiera błąd, który pwightman zauważył. Ponadto nie ma potrzeby przycinania białych znaków. Oto zmodyfikowana wersja:
- (void)adjustFontSizeToFit {
UIFont *font = self.font;
CGSize size = self.frame.size;
for (CGFloat maxSize = self.font.pointSize; maxSize >= self.minimumScaleFactor * self.font.pointSize; maxSize -= 1.f) {
font = [font fontWithSize:maxSize];
CGSize constraintSize = CGSizeMake(size.width, MAXFLOAT);
CGSize labelSize = [self.text sizeWithFont:font constrainedToSize:constraintSize lineBreakMode:NSLineBreakByWordWrapping];
if(labelSize.height <= size.height) {
self.font = font;
[self setNeedsLayout];
break;
}
}
// set the font to the minimum size anyway
self.font = font;
[self setNeedsLayout];
}
Problem, z którym się borykam, polega na tym, że tekst wydaje się wyrównany do lewej niezależnie od tego, co robisz. Aktualizacja: Wygląda na odznaczenie "Zaostrzyć odstęp między literami" rozwiązuje ten problem. – Pierre
Oto rozwiązanie kategorii zaktualizowane do iOS 7 w oparciu o aktualizacje itecedor dla iOS 6.
plik nagłówka:
#import <UIKit/UIKit.h>
@interface UILabel (MultiLineAutoSize)
- (void)adjustFontSizeToFit;
@end
a plik realizacja:
@implementation UILabel (MultiLineAutoSize)
- (void)adjustFontSizeToFit {
UIFont *font = self.font;
CGSize size = self.frame.size;
for (CGFloat maxSize = self.font.pointSize; maxSize >= self.minimumScaleFactor * self.font.pointSize; maxSize -= 1.f)
{
font = [font fontWithSize:maxSize];
CGSize constraintSize = CGSizeMake(size.width, MAXFLOAT);
CGRect textRect = [self.text boundingRectWithSize:constraintSize
options:NSStringDrawingUsesLineFragmentOrigin
attributes:@{NSFontAttributeName:font}
context:nil];
CGSize labelSize = textRect.size;
if(labelSize.height <= size.height)
{
self.font = font;
[self setNeedsLayout];
break;
}
}
// set the font to the minimum size anyway
self.font = font;
[self setNeedsLayout]; }
@end
Nie trzeba stosować minimalnego Współczynnika Skalowania do początkowej wielkości punktu? (np. jeśli współczynnik wynosi 0.5, możesz tu uzyskać bardzo małe czcionki). – iceydee
Masz rację! Będę edytować odpowiedź, aby to odzwierciedlić. – stevenpaulr
Działa jak urok, nie zapomnij ustawić adjustsFontSizeToFitWidth na TAK dla UILabel –
Istnieje metoda na NSString
, -sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode:
który najwyraźniej istnieje od iOS 2.0, ale niestety jest przestarzałe w iOS 7 bez sugerowana alternatywa, ponieważ odradza się automatyczne zmniejszanie rozmiaru czcionki. Naprawdę nie rozumiem stanowiska firmy Apple w tej kwestii, ponieważ używają tego w głównym tekście itd. I myślę, że jeśli rozmiary czcionek mieszczą się w niewielkim zakresie, to jest w porządku. Oto implementacja w Swift przy użyciu tej metody.
var newFontSize: CGFloat = 30
let font = UIFont.systemFontOfSize(newFontSize)
(self.label.text as NSString).sizeWithFont(font, minFontSize: 20, actualFontSize: &newFontSize, forWidth: self.label.frame.size.width, lineBreakMode: NSLineBreakMode.ByWordWrapping)
self.label.font = font.fontWithSize(newFontSize)
Nie jestem świadomy sposobu, w jaki można to osiągnąć bez użycia przestarzałych metod.
Szybka wersja zaadaptowana z @DaGaMs.
Swift 2:
extension UILabel {
func adjustFontSizeToFit(minimumFontSize: CGFloat, maximumFontSize: CGFloat? = nil) {
let maxFontSize = maximumFontSize ?? font.pointSize
for size in stride(from: maxFontSize, to: minimumFontSize, by: -CGFloat(0.1)) {
let proposedFont = font.fontWithSize(size)
let constraintSize = CGSizeMake(bounds.size.width, CGFloat(MAXFLOAT))
let labelSize = ((text ?? "") as NSString).boundingRectWithSize(constraintSize,
options: .UsesLineFragmentOrigin,
attributes: [NSFontAttributeName: proposedFont],
context: nil)
if labelSize.height <= bounds.size.height {
font = proposedFont
setNeedsLayout()
break;
}
}
}
}
SWIFT 3:
extension UILabel {
func adjustFontSizeToFit(minimumFontSize: CGFloat, maximumFontSize: CGFloat? = nil) {
let maxFontSize = maximumFontSize ?? font.pointSize
for size in stride(from: maxFontSize, to: minimumFontSize, by: -CGFloat(0.1)) {
let proposedFont = font.withSize(size)
let constraintSize = CGSize(width: bounds.size.width, height: CGFloat(MAXFLOAT))
let labelSize = ((text ?? "") as NSString).boundingRect(with: constraintSize,
options: .usesLineFragmentOrigin,
attributes: [NSFontAttributeName: proposedFont],
context: nil)
if labelSize.height <= bounds.size.height {
font = proposedFont
setNeedsLayout()
break;
}
}
}
}
Nie działa w ogóle –
Odpowiedź oznaczony jako rozwiązania jest hacky i niedokładne. UILabel będzie je obsługiwać automatycznie jeśli ustawić następujące właściwości poprawnie:
numberOfLines
musi być niezerowe
adjustsFontSizeToFitWidth
musi być YES
lineBreakMode
koniecznością nie być NSLineBreakByCharWrapping
lub NSLineBreakByWordWrapping
Udało mi się użyć: numberOfLines = 0, lineBreakMode = NSLineBreakByTruncatingTail (lub NSLineBreakByTruncatingHead lub NSLineBreakByTruncatingMiddle) z ograniczeniem wysokości na etykiecie. –
To powinna być zaakceptowana odpowiedź. –
znalazłem ten link http://beckyhansmeyer.com/2015/04/09/autoshrinking-text-in-a-multiline-uilabel/
Problem można rozwiązać za pomocą Kreatora interfejsu w 3 prostych krokach: „Minimalny rozmiar czcionki”
- Set „autoshrink” do
- Ustaw czcionkę do swojej największego pożądanego rozmiaru czcionki (20) i ustawić Linie do, powiedzmy, 10, które w moim przypadku były tak liczne, jak pasowałyby do etykiety przy tym rozmiarze czcionki.
- Następnie zmiana „Linia Breaks” z „zawijania” do „Obetnij Tail”.
Nadzieję, że to pomaga!
Napisałem małą kategorię na UILabel na podstawie powyższej odpowiedzi "The Dude", aby osiągnąć tę funkcję.
Musiałem zmodyfikować ten sens za pomocą 'NSStringDrawingTruncatesLastVisibleLine | NSStringDrawingUsesLineFragmentOrigin', aby działało. – DevAndArtist
Dla UIButton, tylko te linie pracują dla mnie:
self.centerBtn.titleLabel.numberOfLines = 2;
self.centerBtn.titleLabel.textAlignment = NSTextAlignmentCenter;
self.centerBtn.titleLabel.adjustsFontSizeToFitWidth = YES;
nie mogę skomentować stanowisko MontiRabbit powodu reputacji brakuje, więc zrobię nową odpowiedź.Rozwiązanie, które zaproponował (i jej polecający) nie działa na Xcode 7.3 lub lepszym, jest nieprecyzyjne. Aby działać w ujęć, miałem:
- ustawiona szerokość ograniczenie (czysty szerokość lub ogon & ołowiu)
- SET się ograniczenia do wysokości (to jest bardzo ważne, zazwyczaj AUTORESIZE nie ma ustawić wysokość etykiety)
- set „autoshrink” własność do „Minimalna waga czcionki” lub „Minimalny rozmiar czcionki” (prace w obu przypadkach)
- set „Linia Breaks” własność do „Obetnij ogon”
- set " Linie "do niezerowej wartości
Mam nadzieję, że pomoże! ;)
Ustawienie linii Przerwanie na "Obcinanie ogona" jest sprzeczne z intuicją, nie powinno być konieczne i powoduje, że magia nagle ma miejsce, gdy wszystko inne ustawia się tak, jak tego oczekujesz. Dzięki! Potwierdzenie ograniczenia wysokości nie musi być stałą wysokością, może po prostu dołączyć ją do rozmiaru kontenera lub jego części. –
@DuncanBabbage, nie ma za co! Możemy więc powiedzieć, że wysokość etykiety musiała być obliczana przez kompilator, w jakiś sposób z ograniczeniem wysokości lub z referencją rodzica! – Nem
Użyłem rozwiązania Swift 3 @ wbarksdale, ale stwierdziłem, że długie słowa zostały obcięte w środku. Aby zachować słowa nienaruszone, musiałem zmodyfikować w następujący sposób:
extension UILabel {
func adjustFontSizeToFit(minimumFontSize: CGFloat, maximumFontSize: CGFloat? = nil) {
let maxFontSize = maximumFontSize ?? font.pointSize
let words = self.text?.components(separatedBy: " ")
var longestWord: String?
if let max = words?.max(by: {$1.characters.count > $0.characters.count}) {
longestWord = max
}
for size in stride(from: maxFontSize, to: minimumFontSize, by: -CGFloat(0.1)) {
let proposedFont = font.withSize(size)
let constraintSize = CGSize(width: bounds.size.width, height: CGFloat(MAXFLOAT))
let labelSize = ((text ?? "") as NSString).boundingRect(with: constraintSize,
options: .usesLineFragmentOrigin,
attributes: [NSFontAttributeName: proposedFont],
context: nil)
let wordConstraintSize = CGSize(width: CGFloat(MAXFLOAT), height: CGFloat(MAXFLOAT))
let longestWordSize = ((longestWord ?? "") as NSString).boundingRect(with: wordConstraintSize,
options: .usesFontLeading,
attributes: [NSFontAttributeName: proposedFont],
context: nil)
if labelSize.height <= bounds.size.height && longestWordSize.width < constraintSize.width {
font = proposedFont
setNeedsLayout()
break
}
}
}
}
Spróbuj tego:
Tak czy podklasy UILabel lub zadzwoń adjustFontSize metodę po ustawieniu właściwości tekstu na etykiecie
override var text : String? { didSet { self.adjustFontSize() } }
func adjustFontSize()
{
var lineCount = self.string.components(separatedBy: "\n").count - 1
var textArray = self.string.components(separatedBy: " ")
var wordsToCompare = 1
while(textArray.count > 0)
{
let words = textArray.first(n: wordsToCompare).joined(separator: " ")
let wordsWidth = words.widthForHeight(0, font: self.font)
if(wordsWidth > self.frame.width)
{
textArray.removeFirst(wordsToCompare)
lineCount += 1
wordsToCompare = 1
}
else if(wordsToCompare > textArray.count)
{
break
}
else
{
wordsToCompare += 1
}
}
self.numberOfLines = lineCount + 1
}
extension UILabel{
func adjustFont(minSize:Int, maxSize:Int){
var newFont = self.font
for index in stride(from: maxSize, to: minSize, by: -1) {
newFont = UIFont.systemFont(ofSize: CGFloat(index))
let size = CGSize(width: self.frame.width, height: CGFloat(Int.max))
let size2 = (self.text! as NSString).boundingRect(with: size, options: [.usesLineFragmentOrigin, .usesFontLeading], attributes: [NSAttributedStringKey.font:newFont!], context: nil).size
if size2.height < self.frame.size.height{
break
}
}
self.font = newFont
}
}
należy również przypisać wartość do właściwości numberOfLines pakietu UILabel.
- 1. Tekst przycisku nie z wieloma liniami
- 2. UILabel z 2 liniami, jak obcinać każdą linię niezależnie?
- 3. Jak uzyskać etykietę z wieloma liniami w MFC
- 4. Excel: Komórka z wieloma liniami tekstu w jednym wierszu tekstu
- 5. iOS. Określ ostatnią szerokość linii UILabel
- 6. Skalowanie z liniami do tablicy
- 7. Łańcuch echa do pliku .txt z wieloma liniami - z plikiem wsadowym Windows
- 8. UIPickerView z Multiline UILabel
- 9. Temat Android Holo nie obejmuje elementów rozwijanych z wieloma liniami podziału
- 10. Rysowanie pojedynczego wykresu liniowego Google z wieloma liniami przy użyciu JSON
- 11. Ulepsz UILabel i tappable (tvOS)
- 12. Wykres linii D3 z dowolnie wieloma liniami (i konkretnym formatem danych)
- 13. Ustawianie tekstu UILabel na int?
- 14. iOS - Cień rozprzestrzeniony na UILabel
- 15. UILabel ustawiony na środek widoku
- 16. AVPlayer - UILabel niewidoczny na wideo
- 17. Jak utworzyć obraz z UILabel?
- 18. programowy wpis bloku tekstu z liniami podziału
- 19. Problem z nowymi liniami, gdy używam toprettyxml()
- 20. Niepoprawny rozmiar UILabel dla pojedynczego wiersza tekstu z lineSpacing i wieloma kolorami
- 21. Cień region między dwiema liniami z ggplot
- 22. Logika za złożonymi liniami
- 23. instacji UILabel
- 24. Rysunek z wieloma kolorami na płótnie
- 25. Aplikacja na iOS z wieloma brandingami
- 26. Faye na Heroku: Problemy z wieloma domenami
- 27. Słownik C# z wieloma wartościami na klucz
- 28. Przepis na URL IIS - z wieloma domenami
- 29. Ilekroć Cron z wieloma projektami na serwerze
- 30. Słownik 2d z wieloma kluczami na wartość
Nie działa dla mnie. –