Ich habe meine benutzerdefinierte Zelle in IB entworfen, sie in Unterklassen unterteilt und meine Steckdosen mit meiner benutzerdefinierten Klasse verbunden. Ich habe drei Unteransichten im Zelleninhalt: UIView (cdView) und zwei Labels (titleLabel und emailLabel). Abhängig von den für jede Zeile verfügbaren Daten möchte ich manchmal, dass UIView und zwei Beschriftungen in meiner Zelle angezeigt werden und manchmal nur zwei Beschriftungen. Ich versuche, Einschränkungen auf diese Weise festzulegen, wenn ich die UIView-Eigenschaft auf versteckt setze oder sie aus der Übersicht entferne. Die beiden Beschriftungen werden nach links verschoben. Ich habe versucht, die führende UIView-Einschränkung für 10 Pixel auf Superview (Zelleninhalt) und für 10 Pixel auf UILabels führende Einschränkung für die nächste Ansicht (UIView) zu setzen. Später in meinem Code
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(IndexPath *)indexPath {
...
Record *record = [self.records objectAtIndex:indexPath.row];
if ([record.imageURL is equalToString:@""]) {
cell.cdView.hidden = YES;
}
Ich verstecke meine cell.cdView und möchte, dass die Beschriftungen nach links verschoben werden, jedoch in Cell an derselben Position bleiben. Ich habe versucht, cell.cdView aus der Übersicht zu entfernen, aber es hat auch nicht funktioniert. Ich habe ein Bild angehängt, um zu verdeutlichen, worum es mir geht.
Ich weiß, wie man das programmgesteuert macht, und ich suche nicht nach dieser Lösung. Ich möchte Einschränkungen in IB festlegen und erwarte, dass sich meine Unteransichten dynamisch verschieben, wenn andere Ansichten entfernt oder ausgeblendet werden. Ist dies in IB mit Auto-Layout möglich?
.....
Antworten:
Es ist möglich, aber Sie müssen ein wenig zusätzliche Arbeit leisten. Es gibt ein paar konzeptionelle Dinge, die zuerst aus dem Weg geräumt werden müssen:
In Ihrem Fall bedeutet dies wahrscheinlich:
Was Sie tun müssen, ist , Ihre Etiketten mit Bedacht zu stark einzuschränken. Lassen Sie Ihre vorhandenen Einschränkungen (10 Punkte Platz in der anderen Ansicht) in Ruhe, fügen Sie jedoch eine weitere Einschränkung hinzu: Stellen Sie die linken Ränder Ihrer Beschriftungen mit einer nicht erforderlichen Priorität 10 Punkte vom linken Rand ihrer Übersicht entfernt ein (die standardmäßig hohe Priorität funktioniert wahrscheinlich gut).
Wenn Sie möchten, dass sie sich nach links bewegen, entfernen Sie die linke Ansicht vollständig. Die obligatorische 10-Punkte-Einschränkung für die linke Ansicht verschwindet zusammen mit der Ansicht, auf die sie sich bezieht, und es bleibt nur eine Einschränkung mit hoher Priorität, dass die Beschriftungen 10 Punkte von ihrer Übersicht entfernt sind. Beim nächsten Layoutdurchlauf sollte dies dazu führen, dass sie nach links erweitert werden, bis sie die Breite der Übersicht ausfüllen, jedoch mit Ihrem Abstand um die Kanten.
Eine wichtige Einschränkung: Wenn Sie Ihre linke Ansicht jemals wieder im Bild haben möchten, müssen Sie sie nicht nur wieder in die Ansichtshierarchie einfügen, sondern gleichzeitig alle Einschränkungen wiederherstellen . Dies bedeutet, dass Sie eine Möglichkeit benötigen, Ihre 10pt-Abstandsbeschränkung zwischen der Ansicht und ihren Beschriftungen wiederherzustellen, wenn diese Ansicht erneut angezeigt wird.
quelle
|-(space)-[hidden(0)]-(space)-[visible]
ist effektiv|-(2*space)-[visible]
. Zweitens kann diese Ansicht abhängig von ihrem eigenen Ansichtsunterbaum und den Einschränkungen Einschränkungen auslösen. Sie können nicht garantieren, dass Sie eine Ansicht mit einer Breite von 0 willkürlich einschränken und weiterarbeiten können.|-[otherViews]-[eitherThis][orThis]-|
:), aber ich würde irgendwann auf dieses Problem stoßen.Das Hinzufügen oder Entfernen von Einschränkungen zur Laufzeit ist eine schwere Operation, die die Leistung beeinträchtigen kann. Es gibt jedoch eine einfachere Alternative.
Richten Sie für die Ansicht, die Sie ausblenden möchten, eine Breitenbeschränkung ein. Beschränken Sie die anderen Ansichten mit einer führenden horizontalen Lücke zu dieser Ansicht.
Aktualisieren Sie
.constant
zum Ausblenden die Breitenbeschränkung auf 0.f. Die anderen Ansichten bewegen sich automatisch nach links, um die Position einzunehmen.Siehe meine andere Antwort hier für weitere Details:
Wie ändere ich Beschriftungsbeschränkungen zur Laufzeit?
quelle
Für diejenigen, die nur iOS 8+ unterstützen , ist eine neue boolesche Eigenschaft aktiv . Es wird helfen, nur die erforderlichen Einschränkungen dynamisch zu aktivieren
PS Constraint-Steckdose muss stark und nicht schwach sein.
Beispiel:
Um einen Fehler im Storyboard zu beheben, müssen Sie das
Installed
Kontrollkästchen für eine dieser Einschränkungen deaktivieren .UIStackView (iOS 9+)
Eine weitere Option besteht darin, Ihre Ansichten einzuschließen
UIStackView
. Sobald die Ansicht ausgeblendet ist,UIStackView
wird das Layout automatisch aktualisiertquelle
UIStackView
positioniert seine Ansichten automatisch neu, wenn diehidden
Eigenschaft in einer ihrer Unteransichten geändert wird (iOS 9+).Wechseln Sie in diesem WWDC-Video zu 11:48, um eine Demo zu erhalten:
Geheimnisse des automatischen Layouts, Teil 1
quelle
Mein Projekt verwendet eine benutzerdefinierte
@IBDesignable
Unterklasse vonUILabel
(um Konsistenz in Farbe, Schriftart, Einfügungen usw. sicherzustellen) und ich habe Folgendes implementiert:Dadurch kann die Beschriftungsunterklasse am automatischen Layout teilnehmen, nimmt jedoch keinen Platz ein, wenn sie ausgeblendet ist.
quelle
Für die Googler: Aufbauend auf Max 'Antwort, um das Polsterungsproblem zu lösen, das viele bemerkt haben, habe ich einfach die Höhe des Etiketts erhöht und diese Höhe als Trennzeichen anstelle der tatsächlichen Polsterung verwendet. Diese Idee kann für jedes Szenario mit Ansichten erweitert werden.
Hier ist ein einfaches Beispiel:
In diesem Fall ordne ich die Höhe des Autorenetiketts einem geeigneten zu
IBOutlet
:und wenn ich die Höhe der Einschränkung auf setze, behalten
0.0f
wir die "Auffüllung" bei, da die Höhe der Wiedergabetaste dies zulässt.quelle
NSLayoutConstraint
Ich glaube, dass Sie dieconstant
Eigenschaft Ihrer aktualisieren möchtenauthorLabelHeight
.Verbinden Sie die Einschränkung zwischen uiview und Beschriftungen als IBOutlet und setzen Sie das Prioritätselement auf einen niedrigeren Wert, wenn Sie hidden = YES setzen
quelle
Am Ende habe ich 2 xibs erstellt. Eins mit der linken Ansicht und eins ohne. Ich habe beide im Controller registriert und dann entschieden, welche während cellForRowAtIndexPath verwendet werden soll.
Sie verwenden dieselbe UITableViewCell-Klasse. Der Nachteil ist, dass es eine gewisse Verdoppelung des Inhalts zwischen den xibs gibt, aber diese Zellen sind ziemlich einfach. Der Vorteil ist, dass ich nicht viel Code habe, um das Entfernen der Ansicht, das Aktualisieren von Einschränkungen usw. manuell zu verwalten.
Im Allgemeinen ist dies wahrscheinlich eine bessere Lösung, da es sich um technisch unterschiedliche Layouts handelt und daher unterschiedliche xibs haben sollten.
quelle
In diesem Fall ordne ich die Höhe des Autorenetiketts einem geeigneten IBOutlet zu:
und wenn ich die Höhe der Einschränkung auf 0.0f setze, behalten wir das "Auffüllen" bei, da die Höhe der Wiedergabetaste dies zulässt.
quelle
Verwenden Sie zwei horizontale und vertikale UIStackView-Ansichten. Wenn eine Unteransicht im Stapel ausgeblendet ist, werden andere Stapel-Unteransichten verschoben. Verwenden Sie Verteilung -> Proportional für vertikalen Stapel mit zwei UILabels füllen und müssen Sie für die erste UIView festgelegte Breiten- und Höhenkonstanten festlegen
quelle
Versuchen Sie dies, ich habe unten Code implementiert,
Ich habe eine Ansicht auf ViewController, in der drei weitere Ansichten hinzugefügt wurden. Wenn eine Ansicht ausgeblendet ist, werden zwei weitere Ansichten verschoben. Befolgen Sie die nachstehenden Schritte. ,
1.ViewController.h-Datei
2.ViewController.m
Hoffnung Also diese Logik wird jemandem helfen.
quelle
In meinem Fall setze ich die Konstante der Höhenbeschränkung auf
0.0f
und setze auch diehidden
Eigenschaft aufYES
.Um die Ansicht (mit den Unteransichten) wieder anzuzeigen, habe ich das Gegenteil getan: Ich habe die Höhenkonstante auf einen Wert ungleich Null gesetzt und die
hidden
Eigenschaft auf gesetztNO
.quelle
Ich werde horizontale Stapelansicht verwenden. Es kann den Rahmen entfernen, wenn die Unteransicht ausgeblendet ist.
In der Abbildung unten ist die rote Ansicht der eigentliche Container für Ihren Inhalt und verfügt über 10pt nachgestellten Speicherplatz für die orangefarbene Übersicht (ShowHideView). Verbinden Sie dann ShowHideView mit IBOutlet und zeigen / verbergen / entfernen Sie ihn programmgesteuert.
quelle
Dies ist meine andere Lösung mit Prioritätsbeschränkung. Die Idee ist, die Breite auf 0 zu setzen.
Erstellen Sie eine Containeransicht (orange) und legen Sie die Breite fest.
Erstellen Sie eine Inhaltsansicht (rot) und setzen Sie den nachfolgenden Bereich 10pt auf Übersicht (orange). Beachten Sie die Einschränkungen für den nachgestellten Speicherplatz. Es gibt zwei nachfolgende Einschränkungen mit unterschiedlicher Priorität. Niedrig (= 10) und Hoch (<= 10). Dies ist wichtig, um Mehrdeutigkeiten zu vermeiden.
Setzen Sie die Breite der orangefarbenen Ansicht auf 0, um die Ansicht auszublenden.
quelle
Wie von no_scene vorgeschlagen, können Sie dies definitiv tun, indem Sie die Priorität der Einschränkung zur Laufzeit ändern. Dies war für mich viel einfacher, da ich mehr als eine blockierende Ansicht hatte, die entfernt werden musste.
Hier ist ein Ausschnitt mit ReactiveCocoa:
quelle
Für den Fall, dass dies jemandem hilft, habe ich eine Hilfsklasse für die Verwendung visueller Formatbeschränkungen erstellt . Ich benutze es in meiner aktuellen App.
AutolayoutHelper
Es ist vielleicht ein bisschen auf meine Bedürfnisse zugeschnitten, aber Sie finden es vielleicht nützlich oder möchten es ändern und Ihren eigenen Helfer erstellen.
Ich muss Tim für seine Antwort oben , diese Antwort über UIScrollView und auch dieses Tutorial danken .
quelle
So würde ich meine Ansichten neu ausrichten, um Ihre Lösung zu erhalten:
Ich habe eine eigene Daumenregel erstellt. Wenn Sie eine uiview ausblenden / anzeigen müssen, deren Einschränkungen möglicherweise betroffen sind, fügen Sie alle betroffenen / abhängigen Unteransichten in einer uiview hinzu und aktualisieren Sie die führende / nachfolgende / top / bottom-Einschränkungskonstante programmgesteuert.
quelle
Dies ist eine alte Frage, aber ich hoffe trotzdem, dass es helfen wird. Wenn Sie von Android kommen, haben Sie auf dieser Plattform eine praktische Methode
isVisible
, um es aus der Ansicht auszublenden, aber auch den Rahmen nicht zu berücksichtigen, wenn das Autolayout die Ansicht zeichnet.Mit der Erweiterung und der Erweiterung "uiview" können Sie eine ähnliche Funktion in ios ausführen (nicht sicher, warum sie nicht bereits in UIKit enthalten ist). Hier eine Implementierung in Swift 3:
quelle
Der richtige Weg, dies zu tun, besteht darin, Einschränkungen mit isActive = false zu deaktivieren. Beachten Sie jedoch, dass durch Deaktivieren einer Einschränkung diese entfernt und freigegeben wird, sodass Sie starke Steckdosen für sie haben müssen.
quelle
Die einfachste Lösung ist die Verwendung von UIStackView (horizontal). Zur Stapelansicht hinzufügen: erste Ansicht und zweite Ansicht mit Beschriftungen. Setzen Sie dann die isHidden-Eigenschaft der ersten Ansicht auf false. Alle Einschränkungen werden berechnet und automatisch aktualisiert.
quelle
Ich denke, das ist die einfachste Antwort. Bitte überprüfen Sie, ob es funktioniert:
Überprüfen Sie hier https://www.youtube.com/watch?v=EBulMWMoFuw
quelle