Como definir o índice z do iPhone UIView?

252

Quero mover uma visualização em cima da outra, como posso saber o índice z da visualização e como passar para o topo?

Tattat
fonte

Respostas:

279

UIViewos irmãos são empilhados na ordem em que são adicionados à sua superview. Os UIViewmétodos e propriedades da hierarquia estão lá para gerenciar a ordem de exibição. No 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;

As visualizações dos irmãos são ordenadas de volta à frente na subviewsmatriz. Portanto, a vista superior será:

[parentView.subviews lastObject];

e a vista inferior será:

[parentView.subviews objectAtIndex:0];

Como Kolin Krewinkel disse, [parentView bringSubviewToFront:view]trará a visão para o topo, mas este é apenas o caso se as visões forem todos irmãos na hierarquia.

Nathan Eror
fonte
329

Você pode usar a zPositionpropriedade da camada da vista (é um CALayerobjeto) para alterar o índice z da vista.

theView.layer.zPosition = 1;

Como Viktor Nordling acrescentou, "grandes valores estão no topo. Você pode usar qualquer valor que desejar, incluindo valores negativos". O valor padrão é 0.

Você precisa importar a estrutura QuartzCore para acessar a camada. Basta adicionar esta linha de código na parte superior do seu arquivo de implementação.

#import "QuartzCore/QuartzCore.h"
Daniel diz Restabelecer Monica
fonte
7
Assim como um ajudante, grandes valores estão "no topo". Você pode usar qualquer valor que desejar, incluindo valores negativos.
Viktor Nordling
12
Essa solução é melhor caso você queira que sua visão esteja sempre no topo. Basta definir zPosition para MAXFLOAT
Muhammad Hassan Nasr
27
Acabei de aprender que o zPosition da camada e o manipulador de entrada do UIView estão em duas ordens Z diferentes. É realmente estranho quando seus cliques "passam"
Stephen J
a visão geral das visualizações tem que ser a mesma para que as zPositionobras funcionem?
precisa saber é o seguinte
3
Percebi que, apesar de a vista estar no topo, os cliques passam por ela até os objetos abaixo. Isso deve ser considerado um bug. Estou tentando encontrar uma maneira geral de evitar esse problema, sem ter que desabilitar explicitamente as interações do usuário de quaisquer modos de exibição por baixo.
22415 Bruce Patin
103

IB e Swift

Dado o layout em que o amarelo é a super visão geral e o vermelho, o verde e o azul são subviews irmãos de amarelo,

vistas - vista vermelha no topo

o objetivo é mover uma subvisão (digamos verde) para o topo.

vistas - vista verde no topo

No Interface Builder

No Construtor de interface, tudo o que você precisa fazer é arrastar a exibição que você deseja exibir, de cima para baixo na lista, no esquema de documentos.

ordem de visualizações no Interface Builder

Como alternativa, você pode selecionar a visualização e, em seguida, no menu, vá para Editor> Organizar> Enviar para frente .

Na Swift

Existem algumas maneiras diferentes de fazer isso programaticamente.

Método 1

yellowView.bringSubviewToFront(greenView)
  • Este método é o equivalente programático da resposta do IB acima.

  • Só funciona se as subvisões forem irmãos um do outro.

  • Uma matriz das subvisões está contida yellowView.subviews. Aqui, bringSubviewToFrontmove o greenViewíndice de 0para 2. Isso pode ser observado com

      print(yellowView.subviews.indexOf(greenView))

Método 2

greenView.layer.zPosition = 1
  • Esse método apenas move a posição 3D da camada mais alto (mais perto do usuário) no eixo z. Como o padrão é 0para todas as outras visualizações, o resultado é que greenViewparece que está no topo. No entanto, ele ainda permanece no índice 0da yellowView.subviewsmatriz. No entanto, isso pode causar resultados inesperados, porque coisas como eventos de toque ainda irão primeiro para a exibição com o número de índice mais alto. Por esse motivo, talvez seja melhor seguir o método 1 acima.
  • A zPositionpoderia ser ajustado para CGFloat.greatestFiniteMagnitude( CGFloat(FLT_MAX)em versões mais antigas do Swift) para garantir que ele está no topo.
Suragch
fonte
obrigado por isso ... passei 8 horas tentando descobrir isso. yellowView.bringSubviewToFront (greenView) funcionou perfeitamente.
MizAkita 03/03
Curiosamente, as visualizações de contêineres não respeitam isso! Você precisa movê-los manualmente no código, ao que parece.
Fattie
75
[parentView bringSubviewToFront:view] ;
Kolin Krewinkel
fonte
19

Se você quiser fazer isso através do Interface Builder do XCode, poderá usar as opções de menu em Editor-> Arranjo. Lá você encontrará "Enviar para frente", "Enviar para trás" etc.

Larspars
fonte
E se as opções de Organizar estiverem desabilitadas?
mr5 12/02
9

Dentro da visualização que você deseja trazer para o topo ... (em rápido)

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

Se você estiver usando o cocos2d, poderá ver um problema com [parentView bringSubviewToFront: view], pelo menos não estava funcionando para mim. Em vez de trazer a vista que eu queria para a frente, eu envio as outras vistas de volta, e isso fez o truque.

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

Podemos usar o zPosition no ios

se tivermos uma visualização denominada salonDetailView, por exemplo:@IBOutlet weak var salonDetailView: UIView!

No meu caso veja a imagem

e tenha o UIView for GMSMapView, por exemplo:@IBOutlet weak var mapViewUI: GMSMapView!

Para mostrar o View salonDetailView na parte superior do mapViewUI

use zPosition como abaixo

salonDetailView.layer.zPosition = 1
abhijith k
fonte
poste fotos e códigos diretamente aqui na sua resposta, para facilitar a obtenção do OP.
Skratchi.at 22/03/19
como iniciante, o StackOverflow não permitirá que eu faça isso muito. você pode verificar a imagem problema i.stack.imgur.com/d9Cx3.png
abhijith k
0

Ou use isso

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

conforme aqui

Peter
fonte