Estou escrevendo um aplicativo e preciso alterar a exibição se o usuário estiver olhando para o aplicativo enquanto estiver falando ao telefone.
Eu implementei o seguinte método:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
NSLog(@"viewWillAppear:");
_sv.frame = CGRectMake(0.0, 0.0, 320.0, self.view.bounds.size.height);
}
Mas não está sendo chamado quando o aplicativo retorna ao primeiro plano.
Eu sei que posso implementar:
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameChanged:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
mas eu não quero fazer isso. Prefiro colocar todas as minhas informações de layout no método viewWillAppear: e deixar que isso lide com todos os cenários possíveis.
Eu até tentei chamar viewWillAppear: from applicationWillEnterForeground :, mas não consigo identificar qual é o controlador de exibição atual naquele momento.
Alguém sabe a maneira correta de lidar com isso? Tenho certeza de que estou perdendo uma solução óbvia.
ios
objective-c
iphone
viewwillappear
Philip Walton
fonte
fonte
applicationWillEnterForeground:
para determinar quando seu aplicativo voltou a entrar no estado ativo.isMemberOfClass
ouisKindOfClass
, dependendo de suas necessidades.Respostas:
O método
viewWillAppear
deve ser adotado no contexto do que está acontecendo em seu próprio aplicativo, e não no contexto de seu aplicativo ser colocado em primeiro plano quando você voltar para outro aplicativo.Em outras palavras, se alguém olhar para outro aplicativo ou receber uma ligação telefônica, voltará para o seu aplicativo que estava em segundo plano, o seu UIViewController que já estava visível quando você saiu do aplicativo 'não se importa', por assim dizer - no que diz respeito, nunca desapareceu e ainda é visível - e assim
viewWillAppear
não é chamado.Eu recomendo não ligar para
viewWillAppear
você mesmo - ele tem um significado específico que você não deve subverter! Uma refatoração que você pode fazer para obter o mesmo efeito pode ser a seguinte:Em seguida, você também aciona a
doMyLayoutStuff
partir da notificação apropriada:Não existe uma maneira imediata de saber qual é o UIViewController 'atual' a propósito. Mas você pode encontrar maneiras de contornar isso, por exemplo, existem métodos delegados do UINavigationController para descobrir quando um UIViewController é apresentado nele. Você pode usar isso para rastrear o UIViewController mais recente que foi apresentado.
Atualizar
Se você criar layouts de interface do usuário com as máscaras de redimensionamento apropriadas nos vários bits, às vezes nem precisará lidar com o layout 'manual' da sua interface do usuário - ele é tratado apenas ...
fonte
self.navigationController.topViewController
o fornece efetivamente, ou pelo menos aquele no topo da pilha, que seria o atual se esse código estiver disparando no thread principal em um modo de exibição de contoller. (Poderia ser errado, não tenho jogado com ele um monte, mas parece funcionar.)appDelegate.rootViewController
funcionará também, mas pode retornar umUINavigationController
e, em seguida, você precisará.topViewController
como @MatthewFrederick diz.Rápido
Resposta curta
Use um
NotificationCenter
observador em vez deviewWillAppear
.Resposta longa
Para descobrir quando um aplicativo volta dos bastidores, use um
NotificationCenter
observador em vez deviewWillAppear
. Aqui está um projeto de amostra que mostra quais eventos acontecem quando. (Esta é uma adaptação desta resposta do Objective-C .)Ao iniciar o aplicativo, a ordem de saída é:
Depois de pressionar o botão home e, em seguida, trazer o aplicativo de volta ao primeiro plano, a ordem de saída é:
Portanto, se você estava originalmente tentando usar
viewWillAppear
,UIApplication.willEnterForegroundNotification
provavelmente é o que deseja.Nota
A partir do iOS 9 e posterior, você não precisa remover o observador. A documentação declara:
fonte
Use o Notification Center no
viewDidLoad:
método do seu ViewController para chamar um método e, a partir daí, faça o que você deveria fazer no seuviewWillAppear:
método. LigarviewWillAppear:
diretamente não é uma boa opção.fonte
dealloc
método então.viewWillAppear:animated:
, um dos métodos mais confusos nos SDKs do iOS, na minha opinião, nunca é invocado em tal situação, ou seja, na alternância de aplicativos. Esse método é chamado apenas de acordo com a relação entre a visualização do controlador de visualização e a janela do aplicativo , ou seja, a mensagem é enviada para um controlador de visualização apenas se sua visualização aparecer na janela do aplicativo e não na tela.Quando seu aplicativo fica em segundo plano, obviamente as vistas mais altas da janela do aplicativo não são mais visíveis para o usuário. Na perspectiva da janela do aplicativo, no entanto, elas ainda são as vistas superiores e, portanto, não desapareceram da janela. Em vez disso, essas visualizações desapareceram porque a janela do aplicativo desapareceu. Eles não desapareceram porque desapareceram da janela.
Portanto, quando o usuário volta para o seu aplicativo, ele obviamente aparece na tela, porque a janela aparece novamente. Mas da perspectiva da janela, eles não desapareceram. Portanto, os controladores de exibição nunca recebem a
viewWillAppear:animated
mensagem.fonte
Swift 4.2 / 5
fonte
Apenas tentando facilitar o máximo possível, veja o código abaixo:
fonte