iOS-Äquivalent für den Sichtbarkeitsmodus Android View.GONE

79

Ich entwickle eine App für iOS und verwende das Storyboard mit aktiviertem AutoLayout. Einer meiner View Controller hat einen Satz von 4 Tasten, und unter bestimmten Umständen möchte ich die erste verschwinden lassen.

Wenn ich die setHidden:TRUEMethode verwende, wird der UIButton unsichtbar, nimmt aber offensichtlich immer noch Platz in der Ansicht ein, und das Ergebnis ist ein "Loch", das ich nicht füllen konnte, sodass der verbleibende UIButton zum oberen Rand der Hauptansicht schwebt.

In Android mich einfach hätte verwendet View.GONEstatt View.INVISIBLE, aber in iOS Ich bin fest mit diesem Verhalten , und ich will nicht glauben , dass die einzige Lösung ist , um manuell (ja , ich meine , programmatisch) bewegen , um die verbleibenden Elemente nach oben.

Ich dachte, ich hätte es geschafft, eine Art Einschränkung festzulegen, um alles so automatisch wie in Android zu machen, aber ich hatte kein Glück.

Kann mich jemand in die richtige Richtung weisen, bevor ich Autolayout ausschalte?

Ich benutze den IB, aber ich bin auch mit programmatischen Dingen vertraut.

AKTUALISIEREN:

Das Setzen der Komponentenhöhe auf 0 hilft ebenfalls nicht.

Ich habe so etwas versucht:

UIButton *b;
CGRect frameRect = b.frame;
frameRect.size.height = 0;
b.frame = frameRect;
elbuild
quelle
Wie wäre es, wenn Sie die Höhe der Schaltfläche auf Null setzen?
Cahn
Ich habe so etwas versucht: UIButton * b; CGRect frameRect = b.frame; frameRect.size.height = 0; b.frame = frameRect; Kein Glück :(
elbuild
Ich weiß, dass dies eine super alte Frage ist, aber in Bezug auf Ihr Update hilft es nicht, den Frame auf 0 zu setzen, wenn Sie Autolayout verwenden. Sie müssen die Höhenbeschränkung auf 0 setzen
wyu

Antworten:

40

Das Hinzufügen einer Einschränkung (NSLayoutAttributeHeight), mit der die Höhe der Ansicht auf 0 gesetzt wird, hat bei mir funktioniert:

[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.captchaView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:0]];
Deniz
quelle
11
self.view.addConstraint(NSLayoutConstraint(item: self.captchaView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 0))
Schnelle
1
Dies sollte die Antwort gewesen sein
Rick Royd Aban
2
Was ist, wenn ich die tatsächliche Höhe der gewünschten Ansicht nicht kenne (z. B. etwas später gerenderte Containeransicht)?
A. Petrov
Vielen Dank für die tolle Antwort! Für jemanden kann es brauchen. Ich habe einen Fehler bekommen Unable to simultaneously satisfy constraints. während ich schon Einschränkungen für die Ansicht hatte. Ich löse es durch stackoverflow.com/a/38625419/1270901
Nevin Chen
@iStar Ich habe den gleichen Code verwendet, aber es funktioniert nicht ... stackoverflow.com/questions/45454992/…
Sanjay Mangaroliya
20

Alle Antworten auf diese Fragen sind ineffizient. Der beste Weg, um Android setVisibility gleichzusetzen: Die Methode unter iOS ist, dass StackViewzuerst Komponenten ausgewählt und dann im Editor, eingebettet in, Stapelansicht,

Verbinden Sie die neue Stapelansicht mit IBOutlet und folgen Sie dann:

versteckt:

UIView * firstView = self.svViewFontConfigure.arrangedSubviews[0];
        firstView.hidden = YES;

Sichtweite:

UIView * firstView = self.svViewFontConfigure.arrangedSubviews[0];
        firstView.hidden = NO;

Bei Verwendung der Stapelansicht bleiben alle Einschränkungen erhalten!

Dokument

Ucdemir
quelle
Scheint eigentlich eine wirklich gute Lösung zu sein, aber es ist erwähnenswert, dass iOS9 + benötigt wird.
user3533716
Ich habe Ihre brillante Lösung verwendet (+1 für Sie, vielen Dank !!), aber ich habe über IBOutlet direkt die Ansicht verbunden, die ich ein- und ausblenden wollte, sodass ich nur eine Codezeile eingeben muss! :)
Cristina De Rito
1
Diese Antwort ist eigentlich nicht richtig. Android View.GONE entfernt die Ansicht auf der Benutzeroberfläche. Wenn Sie beispielsweise View.GONE als Element festlegen, werden die Ansichten darunter wiew verschoben. Ihr Vorschlag verbirgt also nur die Ansicht, die View.HIDE entspricht. Schauen Sie sich diese Antwort an: stackoverflow.com/questions/11556607/…
emin deniz
Ich habe nicht auf Android API gesucht ... Aber ich bin ein mobiler Entwickler, daher kenne ich Mechaniker ... In Android mit boolescher Flagge kann die Ansicht angezeigt werden oder nicht (Gone, Visible). Wenn sie aus der Benutzeroberfläche entfernt wird, ist dies schwierig wieder hinzufügen ... aber in ios, es im Layout, aber ohne Leerzeichen .... Darüber hinaus gibt es offiziell ios versteckte Eigenschaft, die stattfinden ... UIStackview versteckte Eigenschaft wie Android View.Gone
Ucdemir
16

Fügen Sie Ihrer Ansicht eine Höhenbeschränkung wie folgt hinzu:Geben Sie hier die Bildbeschreibung ein

Erstellen Sie dann einen Ausgang für die Höhenbeschränkung in Ihrer viewController-Datei wie folgt:Geben Sie hier die Bildbeschreibung ein

& Ändern Sie dann in Ihrer viewDidLoad-Methode die Einschränkungshöhe wie folgt auf 0:

override func viewDidLoad() {
    super.viewDidLoad()
nsLcButtonHeight.constant = 0
}
Ajinkya Patil
quelle
1
Konstante Höhe ist zum Kotzen. Ich verwende gleiche Höhe und Multiplikator, um beispielsweise 25% der übergeordneten Ansicht zu übernehmen. Gibt es ein Beispiel dafür?
user924
8

Um die Androids.GONE-Funktionalität unter iOS zu erreichen, verwenden Sie eine UIStackView. Danach verstecken Sie das Kind nach Position. ( Äpfeldokumentation )

SWIFT 4:

let firstView = cell.rootStackView.arrangedSubviews[0]
    firstView.isHidden = true // first view gone

Es ist ein Beispiel für eine Tabellenzelle. Setzen Sie einfach beide Innenseiten ein Stack viewund holen Sie sich ein Objekt für GONEdas Kind.

Geben Sie hier die Bildbeschreibung ein

Md Imran Choudhury
quelle
1

1) Wenn Ihre Schaltflächen vertikal platziert sind, müssen Sie den heightWert widthauf 0 setzen. Bei horizontal platzierten Schaltflächen versuchen Sie, den Wert auf 0 zu setzen, oder Sie können beide auf 0 setzen.

ODER

2) Sie könnten diesen Ansatz ausprobieren, der button2auf Folgendem setzt button1:

- (void)viewDidLoad
{
[super viewDidLoad];

UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button1 setTitle:@"hello" forState:UIControlStateNormal];

UIButton *button2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[button2 setTitle:@"world" forState:UIControlStateNormal];

[button1 sizeToFit]; [button2 sizeToFit];
[button2 setFrame:CGRectMake(button1.frame.origin.x, button1.frame.origin.y, button2.frame.size.width, button2.frame.size.height)];

[self.view addSubview:button1];
[self.view addSubview:button2];

}
iphondroid
quelle
1

Diese Frage ist ziemlich alt, aber der Schrank, den ich gefunden habe, setzt zusätzliche Einschränkungen (damit die Ansichten in der Ansicht "weg" wissen, was zu tun ist, wenn sie fehlen).

A  which you want to be     A
|  after setting B to gone  |
B                           C
|                               
C                               
  1. Stellen Sie eine Einschränkung mit niedrigerer Priorität (750) von C auf A ein.
  2. Fügen Sie einem NSLayoutConstraint-Array die oberen und unteren Einschränkungen von B hinzu (oder links und rechts, wenn Ihre Ansicht horizontal reduziert werden soll) bConstraints. Tun Sie dies durch:
    1. Steuern Sie das Klicken und ziehen Sie es von der Einschränkung auf den ViewController
    2. Ändern Sie die Verbindung von Outlet zu Outlet Collection
    3. Für den Namen setzen bConstraints.
    4. Klicken Sie auf Verbinden. Dadurch wird ein @IBOutlet var bConstraints: [NSLayoutConstraint]!in Ihrem ViewController erstellt
    5. So fügen Sie zusätzliche Einschränkungen hinzu: Ziehen Sie von der Einschränkung in Storyboard auf den Variablennamen @IBOutlet
  3. Dann verstecke B.

    B.hidden = true
    NSLayoutConstraint.deactivateConstraints(bConstraints)
    
  4. Einblenden

    B.hidden = false
    NSLayoutConstraint.activateConstraints(bConstraints)
    

Je mehr Ansichten Sie haben, desto komplexer wird dies natürlich, da Sie für jede Ansicht zusätzliche Einschränkungen benötigen

wyu
quelle
Es wäre hilfreicher, wenn Sie erklären würden, warum Sie nicht implementieren konnten
wyu
Der zweite Punkt. Ich arbeite allerdings in Xamarin. Ich habe noch keine Lösung für dieses Problem gefunden. Sie wissen nicht, wie Sie ein NSLayoutConstraint-Array mit B-Einschränkungen erstellen sollen. Ich gehe davon aus, dass es programmatisch gemacht wird, wäre schön, den Code dafür zu sehen. Ihre Methode scheint mir der vernünftigste Weg zu sein, um dieses Problem anzugehen, ist jedoch nicht einfach mit nur Pseudocode zu implementieren
Gustavo Baiocchi Costa
Ich habe Xamarin nicht verwendet. In XCode wird folgendermaßen vorgegangen: Klicken Sie bei gedrückter Strg-Taste und ziehen Sie von der Einschränkung in den ViewController (ähnlich wie beim Erstellen eines IBOutlets in xcode). Ändern Sie im angezeigten Popup (sieht ähnlich aus wie i.stack.imgur.com/JegLK.png ) das Dropdown-Menü "Verbindung" von Outletauf Outlet Collection. Für zusätzliche Einschränkungen ziehen Sie bei gedrückter Strg-Taste direkt auf den Variablennamen. Ich kann Sceenshots später heute (in ~ 8 Stunden)
hochladen
Das NSLayoutConstraint-Array ist also die Outlet-Sammlung, die sich hier etwas verlaufen hat, haha, tks, dass Sie sich die Zeit genommen haben, meine Fragen zu beantworten :)
Gustavo Baiocchi Costa
Ja, ich werde die Antwort aktualisieren, um klarer zu sein. Die Lösung funktioniert also für Sie?
Wyu
0

Wie meine Untersuchungen gezeigt haben, kann Ihnen nicht einmal AutoLayout helfen. Sie müssen die Ansichten, die von der optional angezeigten Komponente betroffen sind, manuell ersetzen (in meinem Fall alle Ansichten unten in der optionalen Ansicht, aber Sie können diese sicher anpassen, um alle Schaltflächen rechts von Ihrer optionalen Schaltfläche zu verarbeiten ):

- (IBAction)toggleOptionalView:(id)sender {
    if (!_expanded) {
        self.optionalView.frame = CGRectMake(self.optionalView.frame.origin.x, self.optionalView.frame.origin.y, self.optionalView.frame.size.width, _optionalHeight);
        self.bottomView.frame = CGRectMake(self.bottomView.frame.origin.x, self.bottomView.frame.origin.y+_optionalHeight, self.bottomView.frame.size.width, self.bottomView.frame.size.height);
        _expanded = YES;
    } else {
        self.optionalView.frame = CGRectMake(self.optionalView.frame.origin.x, self.optionalView.frame.origin.y, self.optionalView.frame.size.width, 0);
        self.bottomView.frame = CGRectMake(self.bottomView.frame.origin.x, self.bottomView.frame.origin.y-_optionalHeight, self.bottomView.frame.size.width, self.bottomView.frame.size.height);
        _expanded = NO;

    }
}

Es ist ratsam, die Höhe / Breite der optionalen Komponenten nicht fest zu codieren, da sonst Ihr Code bei jeder Bearbeitung des XIB / Storyboards unterbrochen wird. Ich habe ein Feld float _optionalHeight, das ich in viewDidLoad festgelegt habe, damit es immer auf dem neuesten Stand ist.

Katlu
quelle
0

Sie können auch die Seite oder zumindest bestimmte Zellen der Seite löschen und das Ganze neu definieren. Es ist schnell und funktioniert gut. Ich habe den Code nicht geschrieben, aber in diesem bereits vorhandenen Projekt gefunden, an dem ich arbeite. Erstellen ManagementTableSectionund ManagementTableCellKlassen, um alles zu verwalten. Leider kann ich keinen besser definierten Code bereitstellen.

reckte sich
quelle
0

Aufbauend auf der Antwort von Deniz finden Sie hier eine Lösung, die Einschränkungen in Swift verwendet

Beispiel: Wenn Sie drei Ansichten haben, A_view B_view und C_view vertikal in dieser Reihenfolge ausgerichtet sind und Sie B "ausblenden" und auch die Differenz anpassen möchten, fügen Sie eine Einschränkung hinzu

B_view.removeFromSuperView()
var constr = NSLayoutConstraint(item: C_view, 
                                attribute: NSLayoutAttribute.Top, 
                                relatedBy: NSLayoutRelation.Equal, 
                                toItem: A_view, 
                                attribute: NSLayoutAttribute.Bottom,
                                multiplier: 1,
                                constant: 20)
view.addConstraint(constr)

Konstante ist (in diesem Fall) der vertikale Abstand zwischen C_view und A_view

The4thIceman
quelle
0

Ich habe einer benutzerdefinierten UIView-Implementierung mit dem Namen "visible" eine neue Eigenschaft hinzugefügt, die, wenn sie auf "false" gesetzt ist, eine Einschränkung zum Reduzieren der Ansicht hinzufügt (ich habe nur eine Breitenbeschränkung hinzugefügt, da meine Liste horizontal ist, aber der beste Weg ist möglicherweise, eine hinzuzufügen Höhenbeschränkung von 0).

var visible:Bool = true{
        didSet{
            if(visible){
                clipsToBounds = false;
                removeConstraint(hideConstraint!)
            }else{
                clipsToBounds = true
                addConstraint(hideConstraint!)
            }
        }
    }

Sie müssen die Einschränkung für die Breite Null in der Ansicht initialisieren und als Feld hinzufügen:

private var hideConstraint:NSLayoutConstraint?


func someInitFunction(){
    hideConstraint = NSLayoutConstraint(item: self, attribute: NSLayoutAttribute.Width, relatedBy: NSLayoutRelation.Equal, toItem: nil, attribute: NSLayoutAttribute.NotAnAttribute, multiplier: 1.0, constant: 0.0)
    ...
}
Anthony De Smet
quelle
-3

setHidden: TRUE / FALSE entspricht Android View.GONE / VISIBLE am nächsten.

Die Ansicht nimmt nicht unbedingt Platz ein, wenn sie nicht sichtbar ist!

Ich habe eine ComboBox-Alike mit einer ListView erstellt, die über anderen Ansichten liegt. Ich bin nur bei der Auswahl sichtbar:

Geben Sie hier die Bildbeschreibung ein

thpitsch
quelle
Sie haben vergessen, dass wir in Android auch view.invisible haben ... view.gone ist nicht ähnlich wie setHidden ... seine view.invisible ist ähnlich wie setHidden
Nav