Eu tenho uma exibição personalizada que não está recebendo layoutSubview
mensagens durante a animação.
Eu tenho uma visão que preenche a tela. Ele possui uma subvisão personalizada na parte inferior da tela que é redimensionada corretamente no Interface Builder se eu alterar a altura da barra de navegação. layoutSubviews
é chamado quando a exibição é criada, mas nunca mais. Minhas subvisões estão dispostas corretamente. Se eu desativar a barra de status de chamada, a subvisão layoutSubviews
não é chamada, mesmo que a visualização principal anima seu redimensionamento.
Em que circunstâncias é layoutSubviews
realmente chamado?
Eu autoresizesSubviews
configurei NO
para o meu modo de exibição personalizado. E no Interface Builder, tenho os suportes superior e inferior e a seta vertical definida.
Outra parte do quebra-cabeça é que a janela deve ser tornada chave:
[window makeKeyAndVisible];
caso contrário, as subvisões não serão redimensionadas automaticamente.
fonte
layoutSubviews
. FazinitWithFrame:
comlayoutSubviews
que seja chamado?view1.1
lo chamalayoutSubviews
deview1
e entãolayoutSubviews
deview1.1
. Esta chamada não propaga indefinidamente às superviews, chamando-a emview1.1.1
apenas chamadaslayoutSubviews
noview1.1
eview1.1.1
. Apenas mover-se sem alterar seu tamanho não exigelayoutSubviews
nenhum deles.view1.2
paraview1
,layoutSubviews
deview1.2
eview1
são chamados, maslayoutSubviews
deview1.1
não é chamado. (view1.1
eview1.2
são subvisões deview1
). Ou seja, nem todas as subvisões da visualização de destino são chamadas delayoutSubviews
método .Com base na resposta anterior do @BadPirate, experimentei um pouco mais e criei alguns esclarecimentos / correções. Eu descobri que
layoutSubviews:
será chamado em uma exibição se e somente se:Alguns detalhes relevantes:
layoutSubviews:
é chamado sempre que um UIScrollView rola, pois ele executa a rolagem alterando a origem de seus limites.layoutSubviews:
quando a exibição for eventualmente adicionada a uma hierarquia de exibição .setNeedsLayout
, o que define / gera uma sinalização. Cada iteração do loop de execução, para todas as visualizações na hierarquia de visualizações , esse sinalizador é verificado. Para cada visualização em que a bandeira é encontrada levantada, elalayoutSubviews:
é chamada e a bandeira é redefinida. As visualizações acima da hierarquia serão verificadas / chamadas primeiro.fonte
https://developer.apple.com/library/prerelease/tvos/documentation/WindowsViews/Conceptual/ViewPG_iPhoneOS/CreatingViews/CreatingViews.html#//apple_ref/doc/uid/TP40009503-CH5-SW1
fonte
Alguns dos pontos na resposta do BadPirate são apenas parcialmente verdadeiros:
Para
addSubView
pontoDepende da máscara de redimensionamento automático da exibição (exibição de destino). Se a máscara de redimensionamento automático estiver ativada, o layoutSubview será chamado em cada um
addSubview
. Se não houver máscara de redimensionamento automático, o layoutSubview será chamado somente quando o tamanho do quadro da vista (vista de destino) mudar.Exemplo: se você criou o UIView programaticamente (por padrão, não possui máscara de redimensionamento automático), o LayoutSubview será chamado apenas quando o quadro do UIView não for alterado a todos
addSubview
.É através dessa técnica que o desempenho do aplicativo também aumenta.
Para o ponto de rotação do dispositivo
Isso pode ser verdade apenas quando o seu VC está na hierarquia do VC (raiz em
window.rootViewController
), bem, este é o caso mais comum. No iOS 5, se você criar um VC, mas ele não for adicionado a nenhum outro VC, esse VC não será notado quando o dispositivo girar. Portanto, sua visão não seria notada chamando layoutSubviews.fonte
Rastreei a solução até a insistência do Interface Builder de que as molas não podem ser alteradas em uma exibição com os elementos simulados da tela ativados (barra de status, etc.). Como as molas estavam desativadas para a visualização principal, essa visualização não podia mudar de tamanho e, portanto, foi rolada para baixo por completo quando a barra de chamada apareceu.
Desativar os recursos simulados, redimensionar a exibição e definir as molas corretamente causou a animação e o método foi chamado.
Um problema extra na depuração é que o simulador sai do aplicativo quando o status de chamada é alternado pelo menu. Saia do aplicativo = sem depurador.
fonte
chamando
[self.view setNeedsLayout];
no viewController faz com que seja chamado viewDidLayoutSubviewsfonte
você olhou para layoutIfNeeded?
O trecho da documentação está abaixo. A animação funciona se você chamar esse método explicitamente durante a animação?
layoutIfNeeded Apresenta as subvisões, se necessário.
Discussão Use este método para forçar o layout das subvisões antes de desenhar.
Disponibilidade Disponível no iPhone OS 2.0 e posterior.
fonte
Ao migrar um aplicativo OpenGL do SDK 3 para 4, o layoutSubviews não era mais chamado. Após várias tentativas e erros, eu finalmente abri o MainWindow.xib, selecionei o objeto Window, no inspetor escolheu a guia Window Attributes (mais à esquerda) e marquei "Visible at launch". Parece que no SDK 3 ele ainda usava uma chamada layoutSubViews, mas não no 4.
6 horas de frustração terminadas.
fonte
Um caso bastante obscuro, mas potencialmente importante, quando
layoutSubviews
nunca é chamado, é:fonte