Wie lege ich den iPhone UIView z Index fest?


252

Ich möchte eine Ansicht über eine andere verschieben. Wie kann ich den z-Index der Ansicht ermitteln und wie kann ich nach oben wechseln?

Antworten:


279

UIViewGeschwister werden in der Reihenfolge gestapelt, in der sie zu ihrer Übersicht hinzugefügt werden. Die UIViewHierarchiemethoden und -eigenschaften dienen zum Verwalten der Ansichtsreihenfolge. In UIView.h:

@property(nonatomic,readonly) UIView *superview;
@property(nonatomic,readonly,copy) NSArray *subviews;

- (void)removeFromSuperview;
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index;
- (void)exchangeSubviewAtIndex:(NSInteger)index1 withSubviewAtIndex:(NSInteger)index2;

- (void)addSubview:(UIView *)view;
- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview;
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview;

- (void)bringSubviewToFront:(UIView *)view;
- (void)sendSubviewToBack:(UIView *)view;

Die Geschwisteransichten sind im subviewsArray von hinten nach vorne angeordnet. Die oberste Ansicht ist also:

[parentView.subviews lastObject];

und Ansicht von unten wird sein:

[parentView.subviews objectAtIndex:0];

Wie Kolin Krewinkel sagte, [parentView bringSubviewToFront:view]wird die Ansicht nach oben bringen, aber dies ist nur der Fall, wenn die Ansichten alle Geschwister in der Hierarchie sind.


329

Sie können die zPositionEigenschaft der Ebene der Ansicht (es ist ein CALayerObjekt) verwenden, um den Z-Index der Ansicht zu ändern.

theView.layer.zPosition = 1;

Als Viktor Nordling fügte hinzu : „große Werte auf der linken Seite . Sie alle Werte verwenden , können Sie, auch negative Werte wollen.“ Der Standardwert ist 0.

Sie müssen das QuartzCore-Framework importieren, um auf die Ebene zugreifen zu können. Fügen Sie einfach diese Codezeile oben in Ihre Implementierungsdatei ein.

#import "QuartzCore/QuartzCore.h"

7
Gerade als Helfer stehen große Werte an der Spitze. Sie können beliebige Werte verwenden, einschließlich negativer Werte.
Viktor Nordling

12
Diese Lösung ist besser, wenn Sie möchten, dass Ihre Ansicht immer im Vordergrund steht. Setzen Sie zPosition einfach auf MAXFLOAT
Muhammad Hassan Nasr

27
Ich habe gerade erfahren, dass die zPosition der Ebene und der Eingabe-Handler des UIView auf zwei verschiedenen Z-Ordnungen liegen. Es ist wirklich seltsam, wenn Ihre Klicks "durchgehen"
Stephen J

Muss die Übersicht der Ansichten dieselbe sein, damit zPositionArbeiten ausgeführt werden können?
Hlung

3
Ich bemerkte, dass, obwohl die Ansicht oben ist, Klicks durch sie zu Objekten darunter gehen. Dies sollte als Fehler angesehen werden. Ich versuche, einen allgemeinen Weg zu finden, um dieses Problem zu vermeiden, ohne die Benutzerinteraktionen von Ansichten, die sich darunter befinden, explizit zu deaktivieren.
Bruce Patin

103

IB und Swift

Angesichts des fließenden Layouts, in dem Gelb die Übersicht ist und Rot, Grün und Blau Geschwister-Unteransichten von Gelb sind,

Ansichten - rote Ansicht oben

Das Ziel ist es, eine Unteransicht (sagen wir grün) nach oben zu verschieben.

Ansichten - grüne Ansicht oben

Im Interface Builder

Im Interface Builder müssen Sie lediglich die Ansicht, die oben angezeigt werden soll, an den unteren Rand der Liste in der Dokumentübersicht ziehen.

Reihenfolge der Ansichten in Interface Builder

Alternativ können Sie die Ansicht auswählen und dann im Menü zu Editor> Anordnen> Nach vorne senden gehen .

In Swift

Es gibt verschiedene Möglichkeiten, dies programmgesteuert zu tun.

Methode 1

yellowView.bringSubviewToFront(greenView)
  • Diese Methode ist das programmatische Äquivalent der obigen IB-Antwort.

  • Es funktioniert nur, wenn die Unteransichten Geschwister voneinander sind.

  • Ein Array der Unteransichten ist in enthalten yellowView.subviews. Hier wird bringSubviewToFrontder greenViewvon Index 0nach verschoben 2. Dies kann mit beobachtet werden

      print(yellowView.subviews.indexOf(greenView))

Methode 2

greenView.layer.zPosition = 1
  • Diese Methode verschiebt lediglich die 3D-Position der Ebene höher (näher am Benutzer) auf der Z-Achse. Da die Standardeinstellung 0für alle anderen Ansichten gilt, greenViewsieht das Ergebnis so aus, als ob es oben liegt. Es bleibt jedoch weiterhin im Index 0des yellowView.subviewsArrays. Dies kann jedoch zu unerwarteten Ergebnissen führen, da Dinge wie Tippereignisse immer noch zuerst in die Ansicht mit der höchsten Indexnummer gelangen. Aus diesem Grund ist es möglicherweise besser, mit Methode 1 oben fortzufahren.
  • Das zPositionkönnte auf CGFloat.greatestFiniteMagnitude( CGFloat(FLT_MAX)in älteren Versionen von Swift) gesetzt werden, um sicherzustellen, dass es oben ist.

danke dafür ... ich habe 8 Stunden damit verbracht, das herauszufinden. YellowView.bringSubviewToFront (greenView) hat perfekt funktioniert.
MizAkita

Interessanterweise respektieren Containeransichten dies nicht! Sie müssen sie anscheinend manuell in Code verschieben.
Fattie


19

Wenn Sie dies über den XCode Interface Builder tun möchten, können Sie die Menüoptionen unter Editor-> Arrangement verwenden. Dort finden Sie "Nach vorne senden", "Nach hinten senden" usw.


Was ist, wenn die Optionen von Anordnen deaktiviert sind?
mr5

9

Innerhalb der Ansicht möchten Sie nach oben bringen ... (in schnell)

superview?.bringSubviewToFront(self)

btnDOWN.superview? .bringSubview (toFront: btnDOWN)
Criss

4

Wenn Sie cocos2d verwenden, tritt möglicherweise ein Problem mit [parentView bringSubviewToFront: view] auf, zumindest hat es bei mir nicht funktioniert. Anstatt die gewünschte Ansicht nach vorne zu bringen, sende ich die anderen Ansichten zurück und das hat den Trick getan.

[[[CCDirector sharedDirector] view] sendSubviewToBack:((UIButton *) button)]; 

2

Wir können zPosition in ios verwenden

Wenn wir eine Ansicht mit dem Namen salonDetailView haben, z.@IBOutlet weak var salonDetailView: UIView!

In meinem Fall siehe das Bild

und haben UIView für GMSMapView zB:@IBOutlet weak var mapViewUI: GMSMapView!

Anzeigen der Ansicht salonDetailView oben in der mapViewUI

Verwenden Sie zPosition wie folgt

salonDetailView.layer.zPosition = 1

Bitte posten Sie Fotos und Code direkt hier in Ihrer Antwort, damit OP sie leichter erhalten kann.
skratchi.at

Als Anfänger erlaubt mir StackOverflow nicht, dies zu tun. Sie können das Problembild i.stack.imgur.com/d9Cx3.png
abhijith k

0

Oder benutze dies

- (void)insertSubview:(UIView *)view belowSubview:(UIView*)siblingSubview;

wie hier

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.