2014-06-30 9 views
17

Ich habe eine UILabel, die ich aus Gründen zu einem UITextView konvertieren muss. Wenn ich dies tue, wird der Text trotz der Verwendung derselben (benutzerdefinierten) Schriftart nicht gleich positioniert.Wie kann ich einen UITextView-Layout-Text wie ein UILabel erstellen?

fand ich, dass, wenn ich ein:

textView.textContainer.lineFragmentPadding = 0; 
textView.textContainerInset = UIEdgeInsetsZero; 

Dieser den Text sehr nahe kommt, aber wenn ich die UITextView über Oberseite der UILabel superimpose, sehe ich die Textpositionierung mit jeder neuen Zeile weiter auseinander bekommen.

Screen shot showing text drift.

Die UILabel ist grün, die UITextView schwarz ist. Dies verwendet NSParagraphStyle, um die minimale und maximale Zeilenhöhe auf 15 zu setzen.

Ich habe mit dem Einstellen des Absatzstils und der minimalen/maximalen Zeilenhöhe gespielt, aber ich konnte es nicht genau abgleichen. Ich bin kein Drucker, deshalb verstehe ich nicht unbedingt alle Schriftart-bezogenen Begriffe in der Dokumentation für NSLayoutManager und NSTextContainer und all das.

Ich brauche nur iOS 7 und höher zu unterstützen.

Ich werde nicht zu einem verrückten CoreText-basierten benutzerdefinierten Widget wechseln oder eine zufällige Third-Party-Bibliothek verwenden. Mir geht es gut genug, wenn ich muss. Aber es scheint so, als sollte es eine Kombination zufälliger Eigenschaften geben, um das Layout gleich zu machen.

+0

Meine Schriftart ist HelveticaNeue 13, wenn das hilfreich ist. –

Antwort

13

Ich nahm die Lösung für den Zeilenabstand gefunden at this link und wandte es auf Ihr Problem. Ich habe es unglaublich nahe gebracht, indem ich die Eigenschaft lineSpacing angepasst habe. Ich habe es mit HelveticaNeue Größe 13 getestet und es geschafft, es in die richtige Position zu bringen, wie im Screenshot unten gezeigt.

textView.textContainer.lineFragmentPadding = 0; 
textView.textContainerInset = UIEdgeInsetsZero; 

NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; 

paragraphStyle.lineSpacing = -0.38; 

NSDictionary *attrsDictionary = 
@{ NSFontAttributeName: [UIFont fontWithName:@"HelveticaNeue" size:13.0f], 
NSParagraphStyleAttributeName: paragraphStyle}; 

textView.attributedText = [[NSAttributedString alloc] initWithString:textView.text attributes:attrsDictionary]; 

Screen Shot

+0

Sieht wie eine Problemumgehung aus, aber keine Lösung. Es stellt sich heraus, dass boundingRectWithSize: für NSAttributedString die Größe zurückgibt, die der Größe entspricht, wie sie von UITextView gerendert wird, aber nicht von UILabel. Was ist, wenn ich UILabel verwenden muss, aber die Größe von boundingRectWithSize stimmt nicht damit überein? – vahotm

+0

@ user2327139 Ich stimme zu, dass es sich eher um eine Problemumgehung als um eine Lösung handelt. In Bezug auf Ihre Frage bin ich nicht ganz sicher, was Sie fragen, aber wenn Sie eine neue Frage haben, verwenden Sie den Link "Frage stellen". Fügen Sie einen Link zu dieser Frage hinzu, wenn Sie denken, dass es hilfreich wäre. – Stonz2

+0

Wenn Sie attributierte Zeichenfolgen für UILabel und UITextView verwenden, können Sie den Zeilenabstand in beiden gleich machen. Keine Hacks benötigt. – phatmann

3

Ich habe in der Lage erfolgreich zu ‚Identitätswechsel‘ einen nicht bearbeitbaren mehrzeilige UILabel (wie es geschieht, in einer UITableViewCell Unterklasse) mit einem äquivalenten editierbare mehrzeilige UITextView der Verwendung von folgende:

_textView = UITextView.new; 
_textView.font = _label.font; 
_textView.textColor = _label.textColor; 
_textView.textAlignment = _label.textAlignment; 
_textView.backgroundColor = UIColor.clearColor; 
_textView.textContainer.lineFragmentPadding = 0; 
_textView.textContainerInset = UIEdgeInsetsZero; 

und damit es gut verhalten, wenn tatsächliche Änderungen zu tun, den folgend zu Ihrem UITextViewDelegate hinzufügen:

- (void)textViewDidChange:(UITextView *)textView 
{ 
    ... 
    [textView scrollRangeToVisible:NSMakeRange(textView.text.length, 0)]; 
    [textView scrollRectToVisible:[textView caretRectForPosition:textView.endOfDocument] animated:NO]; 
} 
Verwandte Themen