2013-07-13 13 views
13

Sto provando a utilizzare l'API stringa attribuita di iOS 6 per calcolare la dimensione del testo e ridurre la dimensione del carattere se necessario. Tuttavia, non riesco a farlo funzionare come dice la documentazione.Come rendere NSStringDrawingContext restringente il testo?

NSString *string = @"This is a long text that doesn't shrink as it should"; 

NSStringDrawingContext *context = [NSStringDrawingContext new]; 
context.minimumScaleFactor = 0.5; 

UIFont *font = [UIFont fontWithName:@"SourceSansPro-Bold" size:32.f]; 

NSMutableParagraphStyle *paragraphStyle = [NSMutableParagraphStyle new]; 
paragraphStyle.lineBreakMode = NSLineBreakByClipping; 

NSDictionary *attributes = @{ NSFontAttributeName: font, 
           NSParagraphStyleAttributeName: paragraphStyle }; 

NSAttributedString *attributedString = [[NSAttributedString alloc] initWithString:self.title attributes:attributes]; 

CGRect rect = [attributedString boundingRectWithSize:CGSizeMake(512.f, 512.f) options:NSStringDrawingUsesLineFragmentOrigin context:context]; 

NSLog(@"rect: %@, context: %@", NSStringFromCGRect(rect), context.debugDescription); 

Ma il testo non si riduce e viene troncato. actualScaleFactor è sempre 1. I risultati del registro sono:

rect:{{0, 0}, {431.64801, 80.447998}}, context:<NSStringDrawingContext: 0x14e85770> minimumScaleFactor:0.500000 minimumTrackingAdjustment:0.000000 actualScaleFactor:1.000000 actualTrackingAdjustment:0.000000 totalBounds:{{0, 0}, {431.64801, 80.447998}} 

Il risultato è lo stesso se utilizzo il metodo di disegno effettivo e non il metodo di misurazione. Se rimuovo lo stile di paragrafo, rende il testo a capo e non lo riduce. Se rimuovo lo stile di paragrafo E scelgo una dimensione che consente solo una riga di testo, anche il testo viene troncato anziché essere ridotto. Che c'è? C'è poca documentazione o risorse online che si occupano di NSStringDrawingContext. E sto cercando di evitare l'uso di sizeWithFont:minFontSize:actualFontSize:forWidth:lineBreakMode: che è deprecato in iOS 7.

+2

ho lo stesso problema e appena possibile' t farlo funzionare ... – Pascal

+0

Mi sono imbattuto nello stesso problema su iOS 8.actualScaleFactor non viene aggiornato per il contesto viene utilizzato contextingRectWithSize: options: attributes :: context: o with drawWithRect: options: attributes: context :. –

risposta

8

NSStringDrawingContext di minimumScaleFactor sembra spezzato in iOS 7.

Per quanto posso capire, anche in iOS 6, esso didn lavorare per disegnare; ha funzionato per la misurazione, in modo da poter capire cosa accadrebbe in un contesto in cui lo fa il lavoro per il disegno, come un UILabel. In questo modo, conosci l'altezza minima corretta per l'etichetta.

Oppure, è possibile utilizzare il fattore di scala risultante per ridurre il testo da soli, sapendo che ora si adatta.

Esempio:

- (void)drawRect:(CGRect)rect 
{ 
    // rect is 0,0,210,31 

    NSMutableAttributedString* s = 
     [[NSMutableAttributedString alloc] initWithString: @"This is the army Mister Jones."]; 
    [s addAttributes:@{NSFontAttributeName:[UIFont fontWithName:@"GillSans" size:20]} 
     range:NSMakeRange(0,s.length)]; 

    NSMutableParagraphStyle* para = [[NSMutableParagraphStyle alloc] init]; 
    para.lineBreakMode = NSLineBreakByTruncatingTail; 
    [s addAttributes:@{NSParagraphStyleAttributeName:para} 
     range:NSMakeRange(0,s.length)]; 

    NSStringDrawingContext* con = [[NSStringDrawingContext alloc] init]; 
    con.minimumScaleFactor = 0.5; 

    CGRect result = 
     [s boundingRectWithSize:rect.size 
      options:NSStringDrawingUsesLineFragmentOrigin context:con]; 
    CGFloat scale = con.actualScaleFactor; 
    // ...(could have a check here to see if result fits in target rect)... 

    // fix font to use scale factor, and draw 
    [s addAttributes:@{NSFontAttributeName:[UIFont fontWithName:@"GillSans" size:20*scale]} 
     range:NSMakeRange(0,s.length)]; 
    [s drawWithRect:rect options:NSStringDrawingUsesLineFragmentOrigin context:nil]; 

} 

In iOS 6, scale è di circa 0,85 e si può usare come mostrato di ridurre il testo. Ma in iOS 7, scale rimane a 1, suggerendo che non si sta verificando alcuna riduzione e questa funzionalità di NSStringDrawingContext è ora inutile. Non riesco a capire se si tratta di un bug o se la funzione è stata deliberatamente abbandonata.

+0

Perché non basta passare il contesto a drawWithRect: invece di restringere manualmente il testo? – Andy

+3

@Andy Hai letto quello che ho detto? È rotto. Rotto. Non funziona. Prova tu stesso. Ecco perché sto mostrando all'OP una possibile soluzione alternativa. I workaround sono per cose che sono rotte. Sai, bug. Se fosse possibile passare il contesto a 'drawWithRect:', l'OP non farebbe questa domanda e non risponderei. – matt

+0

sì giusto, mi dispiace, mi sono affrettato a rispondere. Ancora non funziona su iOS 7.0.3: / – Andy

4

Dopo aver cercato su Google per un lungo periodo di tempo, non ho trovato una soluzione funzionante con iOS7. In questo momento io uso la seguente soluzione, sapendo che è molto brutto. Rendo in memoria una UILabel, faccio uno screenshot e disegno quello. UILabel è in grado di ridurre il testo correttamente.

Ma forse qualcuno lo trova utile.

UILabel *myLabel = [[UILabel alloc] initWithFrame:myLabelFrame]; 
    myLabel.font = [UIFont fontWithName:@"HelveticaNeue-BoldItalic" size:16]; 
    myLabel.text = @"Some text that is too long"; 
    myLabel.minimumScaleFactor = 0.5; 
    myLabel.adjustsFontSizeToFitWidth = YES; 
    myLabel.backgroundColor = [UIColor clearColor]; 

    UIGraphicsBeginImageContextWithOptions(myLabelFrame.size, NO, 0.0f); 
    [[myLabel layer] renderInContext:UIGraphicsGetCurrentContext()]; 
    UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 

    [screenshot drawInRect:myLabel.frame]; 
0

Volevo solo pubblicare questa soluzione come ho combattuto con questo per un paio d'ore. Non riuscivo mai a ridurre l'area di testo e avrei sempre tagliato le ultime righe di testo.

La soluzione per me non era aggiungere un contesto e impostarlo su zero. Ho capito questo guardando l'esempio su questo sito. https://littlebitesofcocoa.com/144-drawing-multiline-strings

Nota dopo aver ottenuto la dimensione casella richiama a usare

pageStringSize = [myString boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrsDictionary context:nil]; 

ho ancora bisogno di scorrere ridimensionamento del carattere manualmente:

while (pageStringSize.size.height > 140 && scale > 0.5) { 
      scale = scale - 0.1; 
      font = [UIFont fontWithName:@"Chalkboard SE" size:24.0 *scale]; 
      attrsDictionary = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName,[NSNumber numberWithFloat:1.0], NSBaselineOffsetAttributeName, nil]; 

      pageStringSize = [myString boundingRectWithSize:maxSize options:NSStringDrawingUsesLineFragmentOrigin attributes:attrsDictionary context:nil]; 

     } 
Problemi correlati