As restrições são redefinidas quando o aplicativo está em segundo plano - iOS 13

8

Defina normalmente as restrições iniciais e finais de uma exibição. Defina sua altura como estática 325. E, para a restrição inferior, configurei 2 restrições 1. com a restrição inferior da vista principal para a restrição inferior da visualização. 2. com a restrição inferior da vista principal para a restrição superior da vista. Agora, na ação do usuário, apenas mostro a vista oculta com animação. Portanto, quando a visualização é exibida na tela e o aplicativo entra em segundo plano, a restrição da visualização é alterada automaticamente e a visualização fica oculta. Este problema está ocorrendo apenas em dispositivos iOS 13.

Tentei atualizar suas restrições no viewWillAppear (), mas no iOS 13 o viewWillAppear do ViewControllers também não é chamado quando o aplicativo é ativado em segundo plano. Também não acho que seja uma boa ideia atualizar as restrições.

Storyboard

Arquivo de classe

class ViewController: UIViewController {

    @IBOutlet weak var topConstraint: NSLayoutConstraint!
    @IBOutlet weak var bottomConstraint: NSLayoutConstraint!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + 3) {
            self.topConstraint.isActive = false
            self.bottomConstraint.isActive = true
            UIView.animate(withDuration: 0.3) {
                self.view.layoutIfNeeded()
            }
        }
    }
}

Não quero que minhas restrições sejam alteradas ou atualizadas quando o estado do aplicativo mudar de primeiro plano para segundo plano e vice-versa.

Por favor me ajude com o mesmo.

TIA

Rajat Mishra
fonte
1
Você está misturando restrições com configurações explícitas de quadro, o que geralmente resultará em problemas. Não está muito claro o que você deseja ... Quando a visualização é carregada, você deseja posicionar contentViewabaixo da parte inferior (para que fique "fora da tela"), e deseja animar a visualização da tela ... Então, o aplicativo vai para o fundo , e você deseja que a exibição ainda seja exibida quando o aplicativo voltar ao primeiro plano? Nenhuma nova animação?
21419 DonMag
Sim. Eu quero apenas isso. Na verdade, o código que escrevi em viewWillAppear () que é executado na ação do usuário. Mas, para fins de explicação, criei uma demonstração.
Rajat Mishra
Supondo que sua posição / dimensionamento da animação esteja funcionando corretamente apenas com restrições (sem .frame = ...instruções explícitas ), seu código deverá estar funcionando bem. nãoViewDidLoad() deve ser chamado quando o aplicativo faz a transição de segundo plano para primeiro plano, a menos que você tenha outro código em execução nesse evento.
DonMag

Respostas:

6

Também atendeu a esse problema. Observe que as restrições continuam sendo redefinidas caso não estejam marcadas Installedno Interface Builder. Portanto, como solução alternativa, mantenha todas as restrições Installedno IB e altere o isActiveestado apenas no código.

insira a descrição da imagem aqui

brigadir
fonte
Isso realmente não funcionou para mim, porque se eu definir isActive como false, quando o aplicativo voltar ao plano de fundo e voltar, ele voltará ativo.
Chris Vasselli
2

Você pode alcançar a solução definindo a prioridade e invertendo os valores.

 if !isShowing{
       self.bottomConstraint.priority = UILayoutPriority(rawValue: 250)
       self.topConstraint.priority = UILayoutPriority(rawValue: 750)
   }else{
       self.bottomConstraint.priority = UILayoutPriority(rawValue: 750)
       self.topConstraint.priority = UILayoutPriority(rawValue: 200)
   }
   isShowing = !isShowing
   self.subview.layoutIfNeeded()
Yogeswaran S
fonte
2

Descobri que o problema está ocorrendo apenas no iOS 13.0 e superior. Tente fazer as alterações de restrição no ViewDidLayoutSubviews

      override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
            self.bottomConstraint.isActive = false
            self.topConstraint.isActive = true
    self.view.layoutIfNeeded()
}
Yogeswaran S
fonte
Funcionou como um encanto. Mas por que isso está acontecendo apenas no iOS 13.0? e por que o viewWillAppear não está sendo chamado?
Suhail
1

A solução alternativa que funcionou para mim foi ouvir UIApplication.willEnterForegroundNotificatione definir isActivetodas as restrições neste momento.

Essa notificação parece ser publicada depois que o sistema (incorretamente) redefine todas as restrições para seus estados de IB e antes que o aplicativo se torne visível novamente. Portanto, é o momento perfeito para corrigir as restrições.

Chris Vasselli
fonte
0

se você precisar saber "como posso informar quando os aplicativos ficam em segundo plano em primeiro plano". Você deve usar o NotificationCenter para enviar um sinal para todos. Mas essa não é uma boa prática.

Talvez você possa dizer qual é o seu objetivo, e podemos oferecer uma abordagem diferente.

Emre Gürses
fonte
0

Bem, eu tenho a solução. Na verdade, não podemos dizer que é a solução. Acabei de executar o mesmo código nos dispositivos iOS 13.1 ou superior e o problema desapareceu. Então, por enquanto, posso dizer que esse problema ocorre apenas no iOS 13.0.

Rajat Mishra
fonte