2012-10-18 8 views
5

Ho una linea multipla UILabel (numberOfLines = 0). La larghezza può cambiare in fase di esecuzione e talvolta questo porta al troncamento e/o al re-wrapping. Alcuni esempi illustrano questa migliore:Come capire quando una UILabel verrà troncata e/o la sua posizione di interruzione di linea cambierà

Esempio 1: la riduzione in larghezza porta ad un diverso punto di interruzione di linea

enter image description here enter image description here

Esempio 2: la riduzione della larghezza porta a troncamento

enter image description here enter image description here

Esempio 3: la riduzione di larghezza conduce sia troncamento ed una posizione diversa riga rottura

enter image description here enter image description here

Esempio 4: la riduzione di larghezza non ha alcun effetto sulla troncatura o linea posizione di break

enter image description here enter image description here

Dato che questo cambio di formattazione può essere piuttosto fastidioso, ho intenzione di mascherarlo dietro alcune animazioni (probabilmente una dissolvenza in entrata/uscita). Tuttavia, il primo ostacolo è l'identificazione di quando è il che ho bisogno di fare questo. Non voglio applicare l'animazione ogni volta che l'etichetta si ridimensiona, solo quando causerà un cambiamento nelle posizioni di troncamento o interruzione di riga.

Come posso verificare questo? Il test dovrebbe restituire SÌ ad esempio 1, 2 e 3, ma NO per esempio 4.

Nota: il ridimensionamento non modificherà mai il numero di righe nel mio esempio.

Nota 2: se qualcuno ha dei tag migliori relativi alla formattazione del testo mi piacerebbe conoscerli - sentiti libero di modificare.

Nota 3: se sei interessato a vedere questo comportamento compiuto, prova la mail.app di Apple sull'iPhone. Quando visualizzi la posta in arrivo, fai scorrere un messaggio di posta elettronica e osserva la dissolvenza in entrata/uscita della linea di riepilogo quando si riavvolge e/o tronca (ma non quando non è necessario).

risposta

2

È possibile conoscere le dimensioni dell'etichetta necessarie per visualizzare una particolare istanza NSString. Ad esempio, è possibile utilizzare che uno:

- (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode

Restituisce la dimensione della stringa se fosse reso con i vincoli specificati.

Quindi, ciò che si vuole è quello di ottenere CGSize di una particolare stringa e verificare se non è più grande allora UILabel dimensioni:

UILabel *label; 
    CGSize sizeNeeded = [label.text sizeWithFont:label.font constrainedToSize:CGSizeMake(label.bounds.size.width, MAXFLOAT)]; 
    if (sizeNeeded.height > label.bounds.size.height) 
    { 
     NSLog(@"String is truncated"); 
    } 

più utili NSString metodi si potrebbe trovare qui: NSString UIKit Additions Reference

Ok, un altro modo di fare quello che vuoi:

1) Creare 2 UILabel con le stesse proprietà ma il secondo (label2) sarà con un altro width.

2) Impostare alpha di label2 su 0.0 in modalità non di modifica.

3) Quando la modalità di modifica inizia rendere tale animazione:

// label1.alpha == 1.0, label2.alpha == 0.0 
{[UIView animateWithDuration:0.5 animations:^{ 
    label1.alpha = 0.0; 
    label2.alpha = 1.0; 
}]; 

4) Quando la modalità di modifica conclude:

{[UIView animateWithDuration:0.5 animations:^{ 
    label1.alpha = 1.0; 
    label2.alpha = 0.0; 
}]; 

Che vi darà lo stesso risultato come in Mail.app

+0

Posso vedere come ciò potrebbe aiutare a identificare se l'etichetta verrà troncata. Ma non penso che mi aiuti per esempio 4? Grazie per il collegamento a proposito. –

+0

Cosa intendi? Risolverà completamente il tuo problema per qualsiasi caso. – Nekto

+0

Hai detto: 'solo quando causerà un cambiamento nelle posizioni di troncamento o interruzione di riga '. Ti do anche il codice su come controllare questo. – Nekto

1

La risposta sopra sta usando un metodo ammortizzato, quindi ho pensato che il seguente codice potrebbe essere utile:

- (BOOL)isLabelTruncated:(UILabel *)label 
{ 
    BOOL isTruncated = NO; 

    CGRect labelSize = [label.text boundingRectWithSize:CGSizeFromString(label.text) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : label.font} context:nil]; 

    if (labelSize.size.width/labelSize.size.height > label.numberOfLines) { 

     isTruncated = YES; 
    } 

    return isTruncated; 
} 
+0

In che modo il rapporto tra le dimensioni dell'etichetta si riferisce al numero di linee? Non riesco a vedere come funziona (sicuramente non è stato quando l'ho testato) – aaroncatlin

1

Utilizzare questo metodo per trovare etichetta troncato in iOS 7.

- (BOOL)isTruncated:(UILabel *)label{ 
     CGSize sizeOfText = [label.text boundingRectWithSize: CGSizeMake(label.bounds.size.width, CGFLOAT_MAX) 
                options: (NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) 
                attributes: [NSDictionary dictionaryWithObject:label.font forKey:NSFontAttributeName] context: nil].size; 

     if (self.frame.size.height < ceilf(sizeOfText.height)) { 
      return YES; 
     } 
     return NO; 
    } 
+0

Questo funziona. Per una soluzione di Autolayout, vedere http://stackoverflow.com/a/26510049/1418457 – onmyway133

2

Soluzione Swift 3

È possibile contare il numero di righe dopo aver assegnato la stringa e confrontarle con il numero massimo di righe dell'etichetta.

import Foundation 
import UIKit 

extension UILabel { 

    func countLabelLines() -> Int { 
     // Call self.layoutIfNeeded() if your view is uses auto layout 
     let myText = self.text! as NSString 
     let attributes = [NSFontAttributeName : self.font] 

     let labelSize = myText.boundingRect(with: CGSize(width: self.bounds.width, height: CGFloat.greatestFiniteMagnitude), options: NSStringDrawingOptions.usesLineFragmentOrigin, attributes: attributes, context: nil) 
     return Int(ceil(CGFloat(labelSize.height)/self.font.lineHeight)) 
    } 

    func isTruncated() -> Bool { 

     if (self.countLabelLines() > self.numberOfLines) { 
      return true 
     } 
     return false 
    } 
} 
Problemi correlati