Überprüfen Sie, ob sich eine Unteransicht in einer Ansicht befindet


96

Ich erstelle eine App, in der ich einer Ansicht eine Unteransicht hinzufüge, indem ich addSubview:eine verwende IBAction. Auf die gleiche Weise sollte, wenn die Schaltfläche mit dieser Taste IBActionerneut berührt wird removeFromSuperview, die hinzugefügte Unteransicht aufgerufen werden IBAction:

PSEUDO-CODE

-(IBAction)showPopup:(id)sender 
{
    System_monitorAppDelegate *delegate = (System_monitorAppDelegate *)[[UIApplication sharedApplication] delegate];
    UIView *rootView = delegate.window.rootViewController.view;

    if([self popoverView] is not on rootView) 
    { 
        [rootView addSubview:[self popoverView]];
    } 
    else 
    {
        [[self popoverView] removeFromSuperview];
    }

}

Antworten:


271

Sie suchen wahrscheinlich nach UIViews -(BOOL)isDescendantOfView:(UIView *)view;in der UIView-Klassenreferenz .

Rückgabewert JA, wenn der Empfänger eine unmittelbare oder entfernte Unteransicht der Ansicht ist oder wenn die Ansicht der Empfänger selbst ist; sonst NEIN.

Sie erhalten einen Code wie:

Ziel c

- (IBAction)showPopup:(id)sender {
    if(![self.myView isDescendantOfView:self.view]) { 
        [self.view addSubview:self.myView];
    } else {
        [self.myView removeFromSuperview];
    }
}

Swift 3

@IBAction func showPopup(sender: AnyObject) {
    if !self.myView.isDescendant(of: self.view) {
        self.view.addSubview(self.myView)
    } else {
        self.myView.removeFromSuperview()
    }
}

2
Funktioniert nicht, fügt nur die Ansicht darüber hinzu. Ich werde den Code bearbeiten, um den realen Fall zu zeigen
Pmerino

@ zad0xsis - Ich verstehe den wirklichen Fall nicht. Wenn Sie die zweite Ansicht mit hinzugefügt addSubview:Methode (was wahrscheinlich der Fall ist das erste Mal), das nächste Mal, werden Sie den anderen Teil erreichen , da die zweite Ansicht jetzt ist ein Subview der ersten. Ist es nicht das, was Sie versucht haben? Sie sehen vielleicht einen anderen Mechanismus aus, als würden Sie einen View Controller modal darstellen?

popoverViewNun , ist eine Unteransicht von rootView (rootViewController). Ich möchte überprüfen, ob es auf dem Bildschirm ist (wenn es rootView als Übersicht hat) und wenn ja, entfernen Sie es oder fügen Sie es hinzu, wenn es nicht ist
pmerino

ist [self popoverView]ein neu popover jedes Mal erstellt Zurückgeben? Es kann keine Ansicht "darüber" hinzugefügt werden, wenn es sich um dieselbe Ansicht handelt. Wenn Sie eine Ansicht hinzufügen, die bereits vorhanden ist, gibt es ein No-Op. Wenn die popoverViewMethode jedes Mal eine neue erstellt, wird sie immer nicht in der Ansichtshierarchie sein
bshirley

1
Eine wichtige Überlegung, die mich hierher gebracht hat: Wenn Sie Unteransichten entfernen und hinzufügen, an denen Sie mit IBOutlet-Eigenschaften (oder Ivars) festhalten, müssen Sie sicherstellen, dass die Eigenschaften (Ivars) stark sind oder dass sie (vor ARC) erhalten bleiben . Wenn Sie bei gedrückter Strg-Taste von einer Ansicht auf einen Controller ziehen, um eine Steckdose zu erstellen, wird diese standardmäßig als schwach erstellt, da davon ausgegangen wird, dass die in der Schreibfeder erstellte Ansicht diese besitzt, sodass Sie keine starke Referenz benötigen. Wenn Sie es dann programmgesteuert entfernen, wird die Zuordnung des Steuerelements aufgehoben und Ihre Referenz auf Null gesetzt (in ARC).
Rhabarber

18

Versuche dies:

-(IBAction)showPopup:(id)sender
{
    if (!myView.superview)
        [self.view addSubview:myView];
    else
        [myView removeFromSuperview];
}

genial! manchmal braucht es myView.view.superview, aber es hat für mich wie Magie funktioniert. Danke @ MarkGranoff
Lior Frenkel

11
    UIView *subview = ...;
    if([self.view.subviews containsObject:subview]) {
        ...
    }

Funktioniert nicht, fügt nur die Ansicht darüber hinzu. Ich werde den Code bearbeiten, um den realen Fall zu zeigen - zad0xsis vor 1 Minute bearbeiten
pmerino

12
@pmerino Herzlichen Glückwunsch, dass Sie so faul sind, dass Sie auch "zad0xsis vor 1 Minute bearbeiten" kopiert haben :-)
Thomas Kekeisen

Ich denke, dies ist teurer als die anderen Lösungen, um ehrlich zu sein, weil es alle Unteransichten durchlaufen muss
SimplyKiwi

4

Das Swift-Äquivalent sieht ungefähr so ​​aus:

if(!myView.isDescendantOfView(self.view)) {
    self.view.addSubview(myView)
} else {
    myView.removeFromSuperview()
}

2

Überprüfen Sie die Übersicht der Unteransicht ...

-(IBAction)showPopup:(id)sender {
    if([[self myView] superview] == self.view) { 
        [[self myView] removeFromSuperview];           
    } else {
        [self.view addSubview:[self myView]];         
    }
}

1

Ihre if-Bedingung sollte wie gehen

if (!([rootView subviews] containsObject:[self popoverView])) { 
    [rootView addSubview:[self popoverView]];
} else {
    [[self popoverView] removeFromSuperview];

}

Dies ist eine geringfügige Änderung der Antwort von Michael Frederick. Gibt es andere Ergebnisse als der verwendete Vincent-Code isDescendantOfView:?
Paulmelnikow

Es ergibt sich absolut ein anderes Ergebnis. Dies prüft nur, ob es sich um eine Kinderansicht handelt, nicht um ein Enkelkind oder ein Urenkelkind usw.
Sami Samhuri

0

Hier haben wir zwei verschiedene Ansichten verwendet. Die übergeordnete Ansicht ist die Ansicht, in der wir nach der Nachkommenansicht suchen und prüfen, ob sie der übergeordneten Ansicht hinzugefügt wurde oder nicht.

if parentView.subviews.contains(descendantView) {
   // descendant view added to the parent view.
}else{
  // descendant view not added to the parent view.
}
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.