Ich habe eine UITextView
in meiner iOS-Anwendung, die eine große Menge Text anzeigt.
Ich blättere diesen Text dann mit dem Versatzrandparameter von UITextView
.
Mein Problem ist, dass das Auffüllen von UITextView
meine Berechnungen verwirrt, da es je nach Schriftgröße und Schriftart, die ich verwende, unterschiedlich zu sein scheint.
Daher stelle ich die Frage: Ist es möglich, die den Inhalt des Inhalts umgebende Polsterung zu entfernen UITextView
?
Freuen Sie sich auf Ihre Antworten!
ios
iphone
cocoa-touch
uikit
uitextview
sniurkst
quelle
quelle
Antworten:
Aktuell für 2019
Es ist einer der albernsten Fehler in iOS.
Die hier angegebene Klasse
UITextViewFixed
ist normalerweise die vernünftigste Lösung insgesamt.Hier ist die Klasse:
Vergessen Sie nicht, scrollEnabled im Inspector zu deaktivieren!
Die Lösung funktioniert ordnungsgemäß im Storyboard
Die Lösung funktioniert zur Laufzeit ordnungsgemäß
Das war's, du bist fertig.
Im Allgemeinen sollte dies in den meisten Fällen alles sein, was Sie benötigen .
Selbst wenn Sie die Höhe der Textansicht ändern on the fly ,
UITextViewFixed
tut in der Regel alles , was Sie brauchen.(Ein häufiges Beispiel für das schnelle Ändern der Höhe ist das Ändern während der Benutzertypen.)
Hier ist das kaputte UITextView von Apple ...
Hier ist
UITextViewFixed
:Beachten Sie, dass Sie natürlich müssen
Schalten Sie scrollEnabled im Inspector aus!
Vergessen Sie nicht, scrollEnabled auszuschalten! :) :)
Einige weitere Probleme
(1) In einigen ungewöhnlichen Fällen - zum Beispiel bei Tabellen mit flexiblen, sich dynamisch ändernden Zellenhöhen - macht Apple eine bizarre Sache: Sie fügen unten zusätzlichen Platz hinzu . Nicht wirklich! Dies müsste eines der ärgerlichsten Dinge in iOS sein.
Hier ist eine "schnelle Lösung", die zu den oben genannten hinzugefügt werden kann und normalerweise bei diesem Wahnsinn hilft.
(2) Manchmal müssen Sie Folgendes hinzufügen, um ein weiteres subtiles Apple-Durcheinander zu beheben:
(3) Wir sollten wohl hinzufügen:
gleich nach
.lineFragmentPadding = 0
inUITextViewFixed
.Aber ... ob Sie es glauben oder nicht ... es funktioniert einfach nicht in aktuellem iOS! (Überprüft im Jahr 2019.) Möglicherweise muss diese Zeile in Zukunft hinzugefügt werden.
Die Tatsache, dass
UITextView
in iOS kaputt ist, ist eines der seltsamsten Dinge im gesamten mobilen Computing. Zehnjähriges Jubiläum dieser Frage und es ist immer noch nicht behoben!Schließlich ist hier eine etwas ähnliche Spitze für Text - Feld : https://stackoverflow.com/a/43099816/294884
Völlig zufälliger Tipp: Wie man das "..." am Ende hinzufügt
Oft verwenden Sie eine UITextView "wie ein UILabel". Sie möchten also, dass Text mit einem Auslassungszeichen "..." abgeschnitten wird.
Wenn ja, fügen Sie im "Setup" eine dritte Codezeile hinzu:
Praktischer Tipp, wenn Sie eine Höhe von Null wünschen, wenn überhaupt kein Text vorhanden ist
Oft verwenden Sie eine Textansicht, um nur Text anzuzeigen. Der Benutzer kann also eigentlich nichts bearbeiten. Sie verwenden die Zeilen "0", um zu bedeuten, dass die Textansicht die Höhe abhängig von der Anzahl der Textzeilen automatisch ändert.
Das ist großartig, aber wenn es überhaupt keinen Text gibt, erhalten Sie leider die gleiche Höhe, als ob es eine Textzeile gibt !! Die Textansicht "geht nie weg".
Wenn Sie möchten, dass es "verschwindet", fügen Sie dies einfach hinzu
(Ich habe es auf '1' gesetzt, damit klar ist, was los ist. '0' ist in Ordnung.)
Was ist mit UILabel?
Wenn nur Text angezeigt wird, bietet UILabel viele Vorteile gegenüber UITextView. UILabel leidet nicht unter den auf dieser QS-Seite beschriebenen Problemen. Der Grund, warum wir alle normalerweise "aufgeben" und nur UITextView verwenden, ist, dass es schwierig ist, mit UILabel zu arbeiten. Insbesondere ist es lächerlich schwierig nur hinzufügen , padding , richtig, zu UILabel. In der Tat finden Sie hier eine vollständige Diskussion darüber, wie Sie UILabel "endlich" korrekt mit Padding versehen können: https://stackoverflow.com/a/58876988/294884 In einigen Fällen ist es manchmal schwierig, ein Layout mit dynamischen Höhenzellen zu erstellen Besser auf die harte Tour mit UILabel.
quelle
self.textView.isScrollEnabled = false
drinnenviewDidLayoutSubviews()
und das hat auch funktioniert. Apple mag es einfach, uns durch Reifen springen zu lassen :)translatesAutoresizingMaskIntoConstraints
. Mit dieser Antwort allein konnte ich nicht alle Ränder (einige seltsame untere Ränder konnten nicht entfernt werden) in einer Ansichtshierarchie mithilfe des automatischen Layouts entfernen. Es befasst sich auch mit der Berechnung von Ansichtsgrößen mitsystemLayoutSizeFitting
, die zuvor aufgrund des Buggys eine ungültige Größe zurückgegeben habenUITextView
Für iOS 7.0 habe ich festgestellt, dass der contentInset-Trick nicht mehr funktioniert. Dies ist der Code, mit dem ich den Rand / das Auffüllen in iOS 7 entfernt habe.
Dies bringt den linken Rand des Textes an den linken Rand des Containers:
Dadurch wird die Oberseite des Texts an der Oberseite des Containers ausgerichtet
Beide Linien werden benötigt, um den Rand / die Polsterung vollständig zu entfernen.
quelle
self.descriptionTextView.textContainerInset = UIEdgeInsetsZero;
lineFragmentPadding
auf 0 ist die Magie, nach der ich gesucht habe. Ich habe keine Ahnung, warum Apple es so schwierig macht, UITextView-Inhalte mit anderen Steuerelementen abzustimmen.lineFragmentPadding
ist nicht dazu gedacht, Ränder zu ändern. Aus den Dokumenten Das Auffüllen von Zeilenfragmenten dient nicht zum Ausdrücken von Texträndern. Stattdessen sollten Sie Einfügungen in Ihrer Textansicht verwenden, die Absatzrandattribute anpassen oder die Position der Textansicht in ihrer Übersicht ändern.Diese Problemumgehung wurde 2009 geschrieben, als IOS 3.0 veröffentlicht wurde. Es gilt nicht mehr.
Ich hatte genau das gleiche Problem, am Ende musste ich es benutzen
Dabei ist nameField a
UITextView
. Die Schriftart, die ich zufällig verwendete, war Helvetica 16 point. Es ist nur eine benutzerdefinierte Lösung für die bestimmte Feldgröße, die ich gezeichnet habe. Dadurch wird der linke Versatz bündig mit der linken Seite und der obere Versatz dort, wo ich ihn für die Box haben möchte, eingezogen.Darüber hinaus scheint dies nur dort zu gelten,
UITextViews
wo Sie die Standardausrichtung verwenden, d. H.Richten Sie sich zum Beispiel nach rechts aus und das
UIEdgeInsetsMake
scheint überhaupt keinen Einfluss auf die rechte Kante zu haben.Zumindest können Sie mit der Eigenschaft .contentInset Ihre Felder an den "richtigen" Positionen platzieren und die Abweichungen berücksichtigen, ohne Ihre zu versetzen
UITextViews
.quelle
Aufbauend auf einigen der bereits gegebenen guten Antworten finden Sie hier eine rein auf Storyboard / Interface Builder basierende Lösung, die unter iOS 7.0+ funktioniert
Legen Sie die benutzerdefinierten Laufzeitattribute von UITextView für die folgenden Schlüssel fest:
quelle
Unter iOS 5
UIEdgeInsetsMake(-8,-8,-8,-8);
scheint das großartig zu funktionieren.quelle
Ich würde auf jeden Fall Antworten mit fest codierten Werten vermeiden, da sich die tatsächlichen Ränder mit den Einstellungen für die Schriftgröße des Benutzers usw. ändern können.
Hier ist die Antwort von @ user1687195, die ohne Änderung von geschrieben wurde
textContainer.lineFragmentPadding
(da in den Dokumenten angegeben ist, dass dies nicht die beabsichtigte Verwendung ist).Dies funktioniert hervorragend für iOS 7 und höher.
Dies ist praktisch das gleiche Ergebnis, nur ein bisschen sauberer, da die lineFragmentPadding-Eigenschaft nicht missbraucht wird.
quelle
self.textView.textContainer.lineFragmentPadding = 0;
lineFragmentPadding
ist nicht dazu gedacht, die Ränder zu kontrollieren. Deshalb solltest du verwendentextContainerInset
.Storyboard- oder Interface Builder-Lösung mit benutzerdefinierten Laufzeitattributen :
Screenshots sind von iOS 7.1 & iOS 6.1 mit
contentInset = {{-10, -5}, {0, 0}}
.quelle
Alle diese Antworten befassen sich mit der Titelfrage, aber ich wollte einige Lösungen für die Probleme vorschlagen, die im Hauptteil der OP-Frage dargestellt sind.
Größe des Textinhalts
Eine schnelle Möglichkeit, die Größe des Textes im zu berechnen,
UITextView
ist die Verwendung vonNSLayoutManager
:Dies ergibt den gesamten scrollbaren Inhalt, der möglicherweise größer als der
UITextView
Frame des Frames ist. Ich fand das viel genauer alstextView.contentSize
da es tatsächlich berechnet, wie viel Platz der Text einnimmt. Zum Beispiel bei einem leerenUITextView
:Zeilenhöhe
UIFont
hat eine Eigenschaft, mit der Sie schnell die Zeilenhöhe für die angegebene Schriftart ermitteln können. So können Sie schnell die Zeilenhöhe des Textes in IhremUITextView
mit finden:Berechnung der sichtbaren Textgröße
Das Bestimmen der tatsächlich sichtbaren Textmenge ist wichtig für die Behandlung eines "Paging" -Effekts.
UITextView
hat eine Eigenschaft namens,textContainerInset
die tatsächlich einen Rand zwischen dem tatsächlichenUITextView.frame
und dem Text selbst darstellt. Um die tatsächliche Höhe des sichtbaren Rahmens zu berechnen, können Sie die folgenden Berechnungen durchführen:Bestimmen der Paging-Größe
Schließlich jetzt , dass Sie die sichtbaren Textgröße und den Inhalt haben, können Sie schnell feststellen , was Ihre Offsets das sein sollte , durch Subtraktion
textHeight
von dertextSize
:Mit all diesen Methoden habe ich meine Einfügungen nicht berührt und konnte zum Caret oder zu einer beliebigen Stelle im gewünschten Text gehen.
quelle
Sie können die
textContainerInset
Eigenschaft von verwendenUITextView
:textView.textContainerInset = UIEdgeInsetsMake (10, 10, 10, 10);
(oben links unten rechts)
quelle
textContainerInset
Eigenschaft funktioniert bei mir nicht, wenn ich ihn in einen neuen Wert ändern möchte - siehe stackoverflow.com/questions/19422578/… .Unter iOS 10 funktioniert die folgende Zeile zum Entfernen der oberen und unteren Polsterung.
quelle
UIEdgeInset.zero
funktioniert mit XCode 8.3 und iOS 10.3 SimulatorNeueste Swift:
quelle
Hier ist eine aktualisierte Version von Fatties sehr hilfreicher Antwort. Es werden zwei wichtige Zeilen hinzugefügt, die mir geholfen haben, das Layout für iOS 10 und 11 (und wahrscheinlich auch für niedrigere) zum Laufen zu bringen:
Die wichtigen Zeilen sind die beiden
translatesAutoresizingMaskIntoConstraints = <true/false>
Aussagen!Dies entfernt überraschenderweise alle Ränder unter all meinen Umständen!
Obwohl der
textView
nicht der Ersthelfer ist, kann es vorkommen, dass es einen merkwürdigen unteren Rand gibt, der mit dersizeThatFits
in der akzeptierten Antwort genannten Methode nicht gelöst werden kann .Beim Tippen auf die Textansicht verschwand plötzlich der seltsame untere Rand und alles sah so aus, wie es sollte, aber nur sobald die Textansicht fertig ist
firstResponder
.Daher habe ich hier auf SO gelesen , dass das Aktivieren und Deaktivieren
translatesAutoresizingMaskIntoConstraints
hilfreich ist, wenn der Frame / die Grenzen zwischen den Aufrufen manuell festgelegt werden.Glücklicherweise funktioniert dies nicht nur mit der Rahmeneinstellung, sondern auch mit den 2 Zeilen
setup()
zwischen den beidentranslatesAutoresizingMaskIntoConstraints
Aufrufen!Dies ist beispielsweise sehr hilfreich, wenn Sie den Rahmen einer Ansicht mit
systemLayoutSizeFitting
aUIView
berechnen . Gibt die richtige Größe zurück (was vorher nicht der Fall war)!Wie in der ursprünglichen Antwort erwähnt:
Vergessen Sie nicht, scrollEnabled im Inspector zu deaktivieren!
Diese Lösung funktioniert sowohl im Storyboard als auch zur Laufzeit einwandfrei.
Das war's, jetzt bist du wirklich fertig!
quelle
Für Swift 4 Xcode 9
Mit der folgenden Funktion können Sie den Rand / die Auffüllung des Textes in UITextView ändern
so ist in diesem Fall
quelle
Beim Einsetzen der Lösung hatte ich immer noch Polster auf der rechten Seite und am Boden. Auch die Textausrichtung verursachte Probleme. Der einzig sichere Weg, den ich gefunden habe, bestand darin, die Textansicht in eine andere Ansicht zu verschieben, die an Grenzen gebunden ist.
quelle
Hier ist eine einfache kleine Erweiterung, mit der der Standardrand von Apple aus jeder Textansicht in Ihrer App entfernt wird.
Hinweis: Interface Builder zeigt weiterhin den alten Rand an, aber Ihre App funktioniert wie erwartet.
quelle
Für mich (iOS 11 & Xcode 9.4.1) funktionierte es auf magische Weise, die Eigenschaft textView.font nach
UIFont.preferred(forTextStyle:UIFontTextStyle)
Stil einzurichten und auch die erste Antwort, wie von @Fattie erwähnt. Aber die @ Fattie-Antwort hat nicht funktioniert, bis ich die Eigenschaft textView.font festgelegt habe. Andernfalls verhält sich UITextView weiterhin unregelmäßig.quelle
Falls jemand nach der neuesten Swift-Version sucht, funktioniert der folgende Code mit Xcode 10.2 und Swift 4.2 einwandfrei
quelle
Ich habe einen weiteren Ansatz gefunden, bei dem die Ansicht mit Text aus den Unteransichten von UITextView abgerufen und in der layoutSubview-Methode einer Unterklasse eingerichtet wird:
quelle
Das Scrollen in textView wirkt sich auch auf die Position des Texts aus und lässt ihn so aussehen, als wäre er nicht vertikal zentriert. Ich habe es geschafft, den Text in der Ansicht zu zentrieren, indem ich das Scrollen deaktiviert und den oberen Einschub auf 0 gesetzt habe:
Aus irgendeinem Grund habe ich es noch nicht herausgefunden. Der Cursor ist immer noch nicht zentriert, bevor die Eingabe beginnt, aber der Text wird sofort zentriert, wenn ich mit der Eingabe beginne.
quelle
Wenn Sie eine HTML-Zeichenfolge festlegen und die untere Auffüllung vermeiden möchten, stellen Sie bitte sicher, dass Sie keine Block-Tags verwenden, z. B. div, p.
In meinem Fall war dies der Grund. Sie können es einfach testen, indem Sie das Auftreten von Block-Tags durch das span-Tag ersetzen.
quelle
Für SwiftUI
Wenn Sie mit TextView eine eigene Textansicht erstellen
UIViewRepresentable
und die Auffüllung steuern möchten, gehen Sie in IhrermakeUIView
Funktion einfach wie folgt vor :uiTextView.textContainerInset = UIEdgeInsets(top: 10, left: 18, bottom: 0, right: 18)
oder was auch immer du willst.
quelle
quelle