2013-09-23 7 views
5

Viele der Methoden, die ich verwendet habe, um das Layout gedruckter Zeichenfolgen für die Erstellung komplexer PDF-Dokumente zu bestimmen, sind in iOS7 veraltet. Dokumentation ruft die gleiche Methode, wie Ersatz zu verwenden für alle sizeWithFont Methoden, die veraltet sind:Ersatz für sizeWithFont: ForWidth: lineBreakMode:

boundingRectWithSize:options:attributes: 

Das ist für sizeWithFont:ConstrainedTosize:lineBreakMode in Ordnung ist, aber was ist, wenn ich möchte, dass meine Zeichenfolge in einer Zeile nur? Ich weiß nicht, was ich für die maximale Höhe verwenden soll, deshalb habe ich kein Rechteck als Wert für den ersten Parameter.

Hier ist, was ich habe, wenn Sie auf eine bestimmte Größe beschränken.

CGFloat maxHeightAllowable = _maxHeight; 
CGSize issueTitleMaxSize = CGSizeMake(_issueListTitleColWidth - (kColumnMargin *2), maxHeightAllowable); 
NSDictionary *issueTitleAttributes = [NSDictionary dictionaryWithObjectsAndKeys:_bodyFont, NSFontAttributeName, nil]; 
CGRect issueTitleRect = CGRectIntegral([issueTitleText boundingRectWithSize:issueTitleMaxSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:issueTitleAttributes context:nil]); 
CGSize issueTitleSize = issueTitleRect.size; 

Wie würde ich diese gleiche Methode verwenden, wenn ich die maxHeight weiß es nicht, oder tatsächlich, Höhe für eine Zeile ist genau das, was ich herausfinden möchte?

Ich sehe, warum sie in Richtung Kompatibilität für die NSAttributed Strings und Auto-Layout drängen, aber warum diese ablehnen? Das Ersetzen, in meinem Fall, dauert jetzt 4 oder 5 Schritte, wo es früher 1 oder 2 war.

Mit der LineHeight-Eigenschaft der Schriftart, wie von Herrn T vorgeschlagen, habe ich diese Methoden in einer Kategorie, die meine vereinfacht Ersatz.

#import "NSString+SizingForPDF.h" 

@implementation NSString (SizingForPDF) 

-(CGSize)integralSizeWithFont:(UIFont *)font constrainedToSize:(CGSize)maxSize 
{ 
    NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:font, NSFontAttributeName, nil]; 
    CGRect rect = CGRectIntegral([self boundingRectWithSize:maxSize options:(NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingUsesFontLeading) attributes:attributes context:nil]); 
    return rect.size; 
} 

-(CGSize)integralSizeWithFont:(UIFont *)font maxWidth:(CGFloat)maxWidth numberOfLines:(NSInteger)lines 
{ 
    if (lines == 0) { 
     lines = 1; 
    } 
    NSDictionary *attributes = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName]; 
    CGFloat height = font.lineHeight * lines; 
    CGSize maxsize = CGSizeMake(maxWidth, height); 
    CGRect rect = CGRectIntegral([self boundingRectWithSize:maxsize options:NSStringDrawingUsesLineFragmentOrigin|NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesFontLeading attributes:attributes context:nil]); 
    return rect.size; 
} 

@end 

Antwort

15

Wenn Sie die Höhe einer Zeile suchen nur, man konnte nicht nur lineHeight Eigenschaft Ihre Schrift ist verwenden? Ich verwende das, um die Höhe meiner Etiketten festzulegen oder die Höhe der Elemente ohne Probleme vorauszusehen. Ich bin nicht sicher, ob PDF-Dokumente in dieser Hinsicht anders sind.

Darüber hinaus glaube ich, dass diese Funktionen veraltet waren, da diese Reihe von NSString + UIKit-Funktionen (sizeWithFont:..., usw.) auf der UIStringDrawing-Bibliothek basierten, die nicht threadsicher war. Wenn Sie versucht haben, sie nicht im Hauptthread auszuführen (wie bei anderen UIKit-Funktionen), erhalten Sie unvorhersehbare Verhaltensweisen. Insbesondere, wenn Sie die Funktion für mehrere Threads gleichzeitig ausgeführt haben, stürzt Ihre App wahrscheinlich ab. Aus diesem Grund haben sie in iOS 6 die Methode boundingRectWithSize:... für NSAttributedStrings eingeführt. Dies wurde über den NSStringDrawing-Bibliotheken erstellt und ist threadsicher.

In diesem Sinne, wenn Sie nur iOS 6 und iOS 7 unterstützt, dann würde ich definitiv alle Ihre NSString sizeWithFont:... zu NSAttributeString boundingRectWithSize ändern. Es wird Ihnen eine Menge Kopfschmerzen ersparen, wenn Sie eine seltsame Multithreading-Ecke haben! Hier ist, wie ich konvertiert NSString der sizeWithFont:constrainedToSize::

Was früher sein:

NSString *text = ...; 
CGFloat width = ...; 
UIFont *font = ...; 
CGSize size = [text sizeWithFont:font 
       constrainedToSize:(CGSize){width, CGFLOAT_MAX}]; 

Kann leicht ersetzt werden durch:

NSString *text = ...; 
CGFloat width = ...; 
UIFont *font = ...; 
NSAttributedString *attributedText = 
    [[NSAttributedString alloc] 
     initWithString:text 
     attributes:@ 
     { 
      NSFontAttributeName: font 
     }]; 
CGRect rect = [attributedText boundingRectWithSize:(CGSize){width, CGFLOAT_MAX} 
              options:NSStringDrawingUsesLineFragmentOrigin 
              context:nil]; 
CGSize size = rect.size; 

Bitte beachten Sie die Dokumentation erwähnt:

In iOS 7 und später, diese Methode gibt Bruchgrößen (in der Größe Komponente der Rückkehr zurück ed CGRect); Um eine zurückgegebene Größe für die Größe Views zu verwenden, müssen Sie den Wert auf die nächste höhere Ganzzahl mithilfe der Ceil-Funktion erhöhen.

So die berechnete Höhe oder Breite ziehen für die Dimensionierung Ansichten verwendet werden soll, würde ich verwenden:

CGFloat height = ceilf(size.height); 
CGFloat width = ceilf(size.width); 
+0

Ihre Methode so ziemlich das gleiche wie meine, nur verwende ich das CGRectIntegral Makro zu klemmen die Werte zu ganzen Zahlen. Ich habe nie gedacht, die Schriftart für die Zeilenhöhe zu betrachten. Das war die Antwort für mich. Ich benutzte es, um einige neue Methoden in einer Kategorie zu erstellen, die meinen früheren Code leichter ersetzen. –

+1

LineBreakMode wird durch ein NSParagraphStyle-Attribut ersetzt, das zum Attributwörterbuch hinzugefügt werden kann. Ein detailliertes Beispiel dafür finden Sie unter http://stackoverflow.com/a/26894770/338468. –