Il kernel della risposta è nel post di riferimento di Cupcake. Comunque, è possibile utilizzare sizeWithFont:constrainedToSize:lineBreakMode:
per capire quale sia la dimensione di un frame sarebbe con un carattere particolare in un'etichetta di una data larghezza data una parola specifica incarto, ad esempio
CGSize size = [string sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:UILineBreakModeWordWrap];
Set sizeConstraint
essere la stessa larghezza della vostra etichetta, ma impostare l'altezza per essere più grande. Se lo size.height
risultante è più grande di UILabel, la stringa è troppo lunga. In teoria, è possibile rimuovere l'ultimo carattere/parola e riprovare e ripetere finché non si adatta.
Se pensate che le stringhe potrebbero essere molto lunghe, potreste voler andare dall'altra parte, iniziare con una piccola parte della stringa e continuare ad aggiungere caratteri finché non è troppo grande, e quindi conoscete l'ultimo carattere.
Ad ogni modo, questo calcolo iterativo della dimensione può essere abbastanza un'operazione dispendiosa cpu, quindi fate attenzione.
Aggiornamento:
Ecco un algoritmo che restituisce la lunghezza della NSString
che può andare bene nella UILabel
in questione utilizzando il font di default (ma ignorando dimensione minima del font):
- (NSUInteger)fitString:(NSString *)string intoLabel:(UILabel *)label
{
UIFont *font = label.font;
UILineBreakMode mode = label.lineBreakMode;
CGFloat labelWidth = label.frame.size.width;
CGFloat labelHeight = label.frame.size.height;
CGSize sizeConstraint = CGSizeMake(labelWidth, CGFLOAT_MAX);
if ([string sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height > labelHeight)
{
NSString *adjustedString;
for (NSUInteger i = 1; i < [string length]; i++)
{
adjustedString = [string substringToIndex:i];
if ([adjustedString sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height > labelHeight)
return i - 1;
}
}
return [string length];
}
È potrebbe probabilmente renderlo più efficiente se, ad esempio, verifichi la modalità di interruzione delle parole, saltando al separatore di parole successivo e chiamando sizeWithFont
, ma per i piccoli UILabel
s ciò potrebbe essere sufficiente. Se si voleva sfruttare la logica word-wrap per ridurre al minimo il numero di volte che si chiama sizeWithFont
, si potrebbe avere qualcosa di simile:
- (NSUInteger)fitString:(NSString *)string intoLabel:(UILabel *)label
{
UIFont *font = label.font;
UILineBreakMode mode = label.lineBreakMode;
CGFloat labelWidth = label.frame.size.width;
CGFloat labelHeight = label.frame.size.height;
CGSize sizeConstraint = CGSizeMake(labelWidth, CGFLOAT_MAX);
if ([string sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height > labelHeight)
{
NSUInteger index = 0;
NSUInteger prev;
NSCharacterSet *characterSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
do
{
prev = index;
if (mode == UILineBreakModeCharacterWrap)
index++;
else
index = [string rangeOfCharacterFromSet:characterSet options:0 range:NSMakeRange(index + 1, [string length] - index - 1)].location;
}
while (index != NSNotFound && index < [string length] && [[string substringToIndex:index] sizeWithFont:font constrainedToSize:sizeConstraint lineBreakMode:mode].height <= labelHeight);
return prev;
}
return [string length];
}
Forse il set di caratteri utilizzato qui non è abbastanza di destra (dovrebbe includere trattini, per esempio), ma probabilmente è abbastanza vicino e molto più efficiente rispetto al carattere per carattere, se non è necessario farlo.
Questa domanda dovrebbe essere d'aiuto: http://stackoverflow.com/questions/6422742/how-to-know-the-length-of-nsstring-that-fits-a-uilabel-with-fixed-size –
Avevo già guardato prima ma non ha aiutato –
la risposta @Cupcake pubblicata qui dovrebbe aiutarti –