Eu descobri um comportamento estranho em meu aplicativo, onde um conectado IBOutlet
tem seu quadro de visão conectado entre as chamadas em meu controlador de visão para viewWillAppear:
e viewDidAppear:
. Aqui está o código relevante em minha UIViewController
subclasse:
-(void)viewWillAppear:(BOOL)animated {
NSLog(@"%@", self.scrollView);
}
-(void)viewDidAppear:(BOOL)animated {
NSLog(@"%@", self.scrollView);
}
e a saída de log resultante:
MyApp[61880:c07] <UIScrollView: 0x1057eff0; frame = (0 0; 0 0); clipsToBounds = YES; autoresize = TM+BM; gestureRecognizers = <NSArray: 0x10580100>; layer = <CALayer: 0x1057f210>; contentOffset: {0, 0}>
MyApp[61880:c07] <UIScrollView: 0x1057eff0; frame = (0 44; 320 416); clipsToBounds = YES; autoresize = TM+BM; gestureRecognizers = <NSArray: 0x10580100>; layer = <CALayer: 0x1057f210>; contentOffset: {0, 0}>
O que mostra claramente que o quadro está mudando entre as duas chamadas. Eu queria fazer a configuração com a view no viewDidLoad
método, mas se o conteúdo não estiver disponível para eu alterar até que esteja na tela, parece inútil. O que pode estar acontecendo?
iphone
ios
objective-c
uiscrollview
Jumhyn
fonte
fonte
viewDidLayoutSubviews
era o caminho correto a seguir. Eu apenas tive que colocar todo o meu conteúdo em uma subvisualização para que o método não fosse chamado novamente sempre que eu alterasse o quadro da visão principal.Respostas:
Autolayout
fez uma grande mudança em como projetamos e desenvolvemos a GUI de nossas visualizações. Uma das principais diferenças é queautolayout
não altera o tamanho de nossas visualizações imediatamente, mas apenas quando é acionado, ou seja, em um momento específico, mas podemos forçá-lo a recalcular nossas restrições imediatamente ou marcá-las como "em necessidade" de layout. Funciona assim-setNeedDisplay
.O grande desafio para mim foi entender e aceitar que não precisamos mais usar máscaras de redimensionamento automático, e o frame tornou-se uma propriedade inútil para posicionar nossas visualizações. Não precisamos mais pensar sobre a posição da visão, mas devemos pensar como queremos vê-los em um espaço relacionado entre si.
Quando queremos misturar a máscara de redimensionamento antigo e o layout automático, é que surgem os problemas. Devemos pensar na implementação do autolayout muito em breve e tentar evitar misturar a abordagem antiga em uma hierarquia de visualizações baseada no autolayout.
É bom ter uma visualização de contêiner que usa apenas máscaras de redimensionamento automático, como a visualização principal de um controlador de visualização, mas é melhor se não tentarmos misturar.
Eu nunca usei o storyboard, mas provavelmente está correto. Usando o Autolayout, o quadro de suas visualizações é definido quando o mecanismo de layout automático inicia seu cálculo. Tente perguntar a mesma coisa logo após o super
- (void)viewDidLayoutSubviews
método do seu controlador de visualização.Este método é chamado quando o mecanismo de layout automático termina de calcular os quadros de suas visualizações.
fonte
add something on a screen, "just before it appears to the user". The actual answer is indeed to use viewDidLayoutSubviews.
... você vai mostrar essa visão várias vezesDa documentação:
Notifica o controlador de visualização que sua visualização está prestes a ser adicionada a uma hierarquia de visualização.
Notifica o controlador de visualização que sua visualização foi adicionada a uma hierarquia de visualização.
Como resultado, os frames das subvisualizações ainda não foram definidos no
viewWillAppear
:O método apropriado para modificar sua IU antes que a visualização seja apresentada na tela é:
Notifica o controlador de visualização que sua visualização acabou de apresentar suas subvisualizações.
fonte
viewDidLayoutSubviews
será chamado várias vezes e nem sempre com o mesmo frame (acho que às vezes é chamado com CGRectZero na primeira chamada). Ele é chamado para cada subvisão adicionada e outras alterações na visão.ligar
em seu
viewWillAppear
método. Depois você pode acessar a sua moldura e terá o mesmo valor que você imprime noviewDidAppear
fonte
No meu caso, mover todos os métodos relacionados a quadros para
funcionou perfeitamente (eu estava tentando modificar as restrições do storyboard).
fonte