Ich habe eine Ansicht, die vollständig mit dem automatischen Layout programmgesteuert angelegt ist. Ich habe eine UITextView in der Mitte der Ansicht mit Elementen darüber und darunter. Alles funktioniert gut, aber ich möchte UITextView erweitern können, wenn Text hinzugefügt wird. Dies sollte alles darunter drücken, wenn es sich ausdehnt.
Ich weiß, wie man das "Federn und Streben" macht, aber gibt es eine automatische Layout-Methode, um dies zu tun? Der einzige Weg, den ich mir vorstellen kann, besteht darin, die Einschränkung jedes Mal zu entfernen und wieder hinzuzufügen, wenn sie wachsen muss.
ios
uitextview
autolayout
nslayoutconstraint
Tharris
quelle
quelle
Antworten:
Die Ansicht mit UITextView wird
setBounds
von AutoLayout mit ihrer Größe versehen. Das habe ich also getan. In der Übersicht werden zunächst alle anderen Einschränkungen so eingerichtet, wie sie sein sollten. Am Ende habe ich eine spezielle Einschränkung für die Höhe von UITextView festgelegt und diese in einer Instanzvariablen gespeichert.In der
setBounds
Methode habe ich dann den Wert der Konstante geändert.quelle
textViewDidChange
damit sollte dies einige Probleme beim Unterklassen und Schreiben von Code ersparen…textViewDidChange:
Beachten Sie, dass dies nicht aufgerufen wird, wenn Sie programmgesteuert Text zur UITextView hinzufügen.Zusammenfassung: Deaktivieren Sie das Scrollen Ihrer Textansicht und beschränken Sie deren Höhe nicht.
Geben Sie dazu programmgesteuert den folgenden Code ein
viewDidLoad
:Wählen Sie dazu im Interface Builder die Textansicht aus, deaktivieren Sie im Attributinspektor die Option Bildlauf aktiviert und fügen Sie die Einschränkungen manuell hinzu.
Hinweis: Wenn Sie andere Ansichten über / unter Ihrer Textansicht haben, können Sie sie mit a
UIStackView
anordnen.quelle
intrinsicContentSize
diese- (CGSize)intrinsicContentSize { CGSize size = [super intrinsicContentSize]; if (self.text.length == 0) { size.height = UIViewNoIntrinsicMetric; } return size; }
. Sag mir, ob es für dich funktioniert. Habe es nicht selbst getestet.Hier ist eine Lösung für Leute, die es vorziehen, alles mit automatischem Layout zu erledigen:
Im Größeninspektor:
Stellen Sie die Priorität des Inhaltskomprimierungswiderstands vertikal auf 1000 ein.
Verringern Sie die Priorität der Einschränkungshöhe, indem Sie in Einschränkungen auf "Bearbeiten" klicken. Machen Sie es einfach weniger als 1000.
Im Attributinspektor:
quelle
UITextView bietet keine intrinsicContentSize, daher müssen Sie sie in Unterklassen unterteilen und eine bereitstellen. Damit es automatisch wächst, machen Sie die intrinsicContentSize in layoutSubviews ungültig. Wenn Sie etwas anderes als das Standard-ContentInset verwenden (was ich nicht empfehle), müssen Sie möglicherweise die intrinsicContentSize-Berechnung anpassen.
quelle
setScrollEnabled:
, um es immer auf zu setzenNO
, eine Endlosschleife für eine ständig wachsende intrinsische Inhaltsgröße.[textView sizeToFit]
dentextViewDidChange:
Delegaten-Rückruf aufrufen, damit das automatische Layout die Textansicht nach jedem Tastendruck vergrößert oder verkleinert (und alle abhängigen Einschränkungen neu berechnet).-(void)layoutSubviews
und wickeln Sie sie ein gesamten Code-(CGSize)intrinsicContentSize
mitversion >= 7.0f && version < 7.1f
+else return [super intrinsicContentSize];
Sie können dies über das Storyboard tun, indem Sie einfach "Scrolling Enabled" deaktivieren :)
quelle
Ich habe festgestellt, dass dies in Situationen, in denen isScrollEnabled möglicherweise noch auf true gesetzt ist, nicht ungewöhnlich ist, um eine angemessene Interaktion mit der Benutzeroberfläche zu ermöglichen. Ein einfacher Fall hierfür ist, wenn Sie eine automatisch expandierende Textansicht zulassen möchten, die maximale Höhe jedoch in einer UITableView auf einen angemessenen Wert beschränken möchten.
Hier ist eine Unterklasse von UITextView, die ich mir ausgedacht habe und die eine automatische Erweiterung mit automatischem Layout ermöglicht, die Sie jedoch weiterhin auf eine maximale Höhe beschränken können und die verwaltet, ob die Ansicht abhängig von der Höhe scrollbar ist. Standardmäßig wird die Ansicht unbegrenzt erweitert, wenn Sie Ihre Einschränkungen auf diese Weise eingerichtet haben.
Als Bonus gibt es Unterstützung für das Einfügen von Platzhaltertext ähnlich wie bei UILabel.
quelle
Sie können dies auch ohne Unterklassen tun
UITextView
. Schauen Sie sich meine Antwort auf Wie kann ich eine UITextView unter iOS 7 an ihren Inhalt anpassen?Verwenden Sie den Wert dieses Ausdrucks:
die Aktualisierung
constant
dertextView
‚s HöheUILayoutConstraint
.quelle
Eine wichtige Sache zu beachten:
Da UITextView eine Unterklasse von UIScrollView ist, unterliegt es der Eigenschaft automaticAdjustsScrollViewInsets von UIViewController.
Wenn Sie das Layout einrichten und die Textansicht die erste Unteransicht in einer UIViewControllers-Hierarchie ist, werden die contentInsets geändert, wenn automatischAdjustsScrollViewInsets true ist, was manchmal zu unerwartetem Verhalten im automatischen Layout führt.
Wenn Sie also Probleme mit dem automatischen Layout und
automaticallyAdjustsScrollViewInsets = false
den Textansichten haben , versuchen Sie, diese auf dem Ansichts-Controller festzulegen oder die Textansicht in der Hierarchie nach vorne zu verschieben.quelle
Dies ist eher ein sehr wichtiger Kommentar
Der Schlüssel zum Verständnis, warum die Antwort von Vitaminwater funktioniert, sind drei Dinge:
contentOffset
ist wahrscheinlich nichts anderes als:Weitere Informationen finden Sie unter objc scrollview und zum Verständnis der scrollview
Wenn Sie die drei miteinander kombinieren, werden Sie leicht verstehen, dass Sie zulassen müssen, dass die intrinsische contentSize der textView entlang der AutoLayout-Einschränkungen der textView arbeitet, um die Logik zu steuern. Es ist fast so, als ob Sie textView wie ein UILabel funktionieren
Um dies zu erreichen, müssen Sie das Scrollen deaktivieren. Dies bedeutet im Grunde, dass die Größe der scrollView, die Größe der contentSize und im Falle des Hinzufügens einer containerView die Größe der containerView alle gleich ist. Wenn sie gleich sind, haben Sie KEIN Scrollen. Und du hättest . Haben bedeutet, dass Sie nicht nach unten gescrollt haben. Nicht einmal einen Punkt nach unten! Infolgedessen wird die Textansicht vollständig gestreckt.
0
contentOffset
0
contentOffSet
Es ist auch nichts wert, was bedeutet, dass die Grenzen und der Rahmen von scrollView identisch sind. Wenn Sie 5 Punkte nach unten scrollen, ist Ihr contentOffset gleich , während Ihr gleich ist
0
contentOffset
5
scrollView.bounds.origin.y - scrollView.frame.origin.y
5
quelle
Plug-and-Play-Lösung - Xcode 9
Automatische Anordnung ebenso wie
UILabel
mit der Link - Erkennung , Textauswahl , Bearbeitung und Scrollen vonUITextView
.Handelt automatisch
Viele dieser Antworten haben mich zu 90% dorthin gebracht, aber keine war narrensicher.
Wenn Sie diese
UITextView
Unterklasse besuchen, sind Sie gut.quelle
Die Antwort von Vitaminwater funktioniert für mich.
Wenn der Text Ihrer Textansicht während der Bearbeitung nach dem Einstellen auf und ab springt
[textView setScrollEnabled:NO];
, legen Sie ihn festSize Inspector > Scroll View > Content Insets > Never
.Ich hoffe es hilft.
quelle
Platzieren Sie das versteckte UILabel unter Ihrer Textansicht. Beschriftungslinien = 0. Setzen Sie die Einschränkungen von UITextView so, dass sie dem UILabel entsprechen (centerX, centerY, width, height). Funktioniert auch, wenn Sie das Bildlaufverhalten von textView verlassen.
quelle
Übrigens habe ich eine expandierende UITextView mit einer Unterklasse erstellt und die intrinsische Inhaltsgröße überschrieben. Ich habe in UITextView einen Fehler entdeckt, den Sie möglicherweise in Ihrer eigenen Implementierung untersuchen möchten. Hier ist das Problem:
Die erweiterte Textansicht wird verkleinert, um den wachsenden Text aufzunehmen, wenn Sie jeweils einzelne Buchstaben eingeben. Wenn Sie jedoch eine Menge Text einfügen, wird dieser nicht verkleinert, sondern der Text wird nach oben gescrollt und der Text oben ist nicht sichtbar.
Die Lösung: SetBounds überschreiben: in Ihrer Unterklasse. Aus einem unbekannten Grund führte das Einfügen dazu, dass der Wert für bounds.origin.y nicht zee war (33 in jedem Fall, den ich sah). Also habe ich setBounds überschrieben: um die bounds.origin.y immer auf Null zu setzen. Das Problem wurde behoben.
quelle
Hier ist eine schnelle Lösung:
Dieses Problem kann auftreten, wenn Sie die Eigenschaft clipsToBounds in Ihrer Textansicht auf false gesetzt haben. Wenn Sie es einfach löschen, verschwindet das Problem.
quelle
quelle