¿Cómo configurar el índice z del iPhone UIView?

252

Quiero mover una vista encima de otra, ¿cómo puedo saber el índice z de la vista y cómo pasar a la parte superior?

Tattat
fuente

Respuestas:

279

UIViewlos hermanos se apilan en el orden en que se agregan a su supervista. Los UIViewmétodos y propiedades de la jerarquía están ahí para administrar el orden de las vistas. En 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;

Las vistas entre hermanos se ordenan de atrás hacia adelante en la subviewsmatriz. Entonces la vista más alta será:

[parentView.subviews lastObject];

y la vista inferior será:

[parentView.subviews objectAtIndex:0];

Como dijo Kolin Krewinkel, [parentView bringSubviewToFront:view]llevará la vista a la cima, pero este es solo el caso si las vistas son todas hermanas en la jerarquía.

Nathan Eror
fuente
329

Puede usar la zPositionpropiedad de la capa de la vista (es un CALayerobjeto) para cambiar el índice z de la vista.

theView.layer.zPosition = 1;

Como agregó Viktor Nordling , "los valores grandes están en la parte superior. Puede usar los valores que desee, incluidos los valores negativos". El valor predeterminado es 0.

Debe importar el marco QuartzCore para acceder a la capa. Simplemente agregue esta línea de código en la parte superior de su archivo de implementación.

#import "QuartzCore/QuartzCore.h"
Daniel dice reinstalar a Mónica
fuente
77
Como ayudante, los grandes valores están "en la cima". Puede usar cualquier valor que desee, incluidos los valores negativos.
Viktor Nordling
12
Esta solución es mejor en caso de que desee que su vista esté siempre en la parte superior. Simplemente configure zPosition en MAXFLOAT
Muhammad Hassan Nasr el
27
Acabo de enterarme de que la zPosition de la capa y el manejador de entrada de UIView están en dos órdenes Z diferentes. Es realmente extraño cuando tus clics "pasan"
Stephen J
¿La vista general de las vistas tiene que ser la misma para hacer zPositiontrabajos?
Hlung
3
Noté que, a pesar de que la vista está en la parte superior, los clics lo atraviesan a los objetos debajo. Esto debería considerarse un error. Estoy tratando de encontrar una forma general de evitar ese problema, sin tener que deshabilitar explícitamente las interacciones del usuario de las vistas que se encuentran debajo.
Bruce Patin
103

IB y Swift

Dado el diseño fluido en el que el amarillo es la supervista y el rojo, el verde y el azul son subvistas entre hermanos del amarillo,

vistas - vista roja en la parte superior

El objetivo es mover una subvista (digamos verde) a la parte superior.

vistas - vista verde en la parte superior

En Interface Builder

En el Creador de interfaces, todo lo que necesita hacer es arrastrar la vista que desea mostrar en la parte superior al final de la lista en el Esquema de documentos.

orden de vistas en Interface Builder

Alternativamente, puede seleccionar la vista y luego en el menú ir a Editor> Organizar> Enviar al frente .

En veloz

Hay un par de formas diferentes de hacer esto mediante programación.

Método 1

yellowView.bringSubviewToFront(greenView)
  • Este método es el equivalente programático de la respuesta IB anterior.

  • Solo funciona si las subvistas son hermanos entre sí.

  • Una matriz de las subvistas está contenida en yellowView.subviews. Aquí, bringSubviewToFrontmueve el greenViewíndice 0a 2. Esto se puede observar con

      print(yellowView.subviews.indexOf(greenView))

Método 2

greenView.layer.zPosition = 1
  • Este método simplemente mueve la posición 3D de la capa más arriba (más cerca del usuario) en el eje z. Como el valor predeterminado es 0para todas las demás vistas, el resultado es que greenViewparece que está en la parte superior. Sin embargo, todavía permanece en el índice 0de la yellowView.subviewsmatriz. Sin embargo, esto puede causar algunos resultados inesperados, porque cosas como los eventos de tap todavía irán primero a la vista con el número de índice más alto. Por esa razón, podría ser mejor ir con el Método 1 anterior.
  • Se zPositionpodría establecer en CGFloat.greatestFiniteMagnitude( CGFloat(FLT_MAX)en versiones anteriores de Swift) para garantizar que esté en la parte superior.
Suragch
fuente
gracias por esto ... pasé 8 horas tratando de resolver esto. yellowView.bringSubviewToFront (greenView) funcionó perfectamente.
MizAkita
Curiosamente, las vistas de contenedores no respetan esto. Parece que debes moverlos manualmente en el código.
Fattie
75
[parentView bringSubviewToFront:view] ;
Kolin Krewinkel
fuente
19

Si desea hacer esto a través del Creador de interfaces de XCode, puede usar las opciones del menú en Editor-> Arreglo. Allí encontrará "Enviar al frente", "Enviar al fondo", etc.

larspars
fuente
¿Qué pasa si las opciones de Arrange están deshabilitadas?
Mr5
9

Dentro de la vista que desea llevar a la cima ... (en forma rápida)

superview?.bringSubviewToFront(self)
Carter Medlin
fuente
btnDOWN.superview? .bringSubview (toFront: btnDOWN)
Criss del
4

Si está utilizando cocos2d, puede ver un problema con [parentView bringSubviewToFront: view], al menos no me funcionaba. En lugar de traer la vista que quería al frente, envié las otras vistas y eso funcionó.

[[[CCDirector sharedDirector] view] sendSubviewToBack:((UIButton *) button)]; 
Madhav Sbss
fuente
2

Podemos usar zPosition en ios

si tenemos una vista llamada salonDetailView, por ejemplo:@IBOutlet weak var salonDetailView: UIView!

En mi caso ver la imagen

y tener UIView para GMSMapView, por ejemplo:@IBOutlet weak var mapViewUI: GMSMapView!

Para mostrar la vista salonDetailView superior del mapaViewUI

use zPosition como se muestra a continuación

salonDetailView.layer.zPosition = 1
abhijith k
fuente
publique fotos y código directamente aquí en su respuesta, para que OP pueda obtenerlo más fácilmente.
skratchi.at
como principiante, StackOverflow no me permitirá hacer eso, lo siento. puede verificar la imagen del problema i.stack.imgur.com/d9Cx3.png
abhijith k
0

O usa esto

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

según aquí

Peter
fuente