Las restricciones se restablecen cuando la aplicación pasa a segundo plano - iOS 13

8

He establecido normalmente las restricciones iniciales y finales de una vista. He establecido su altura en estática 325. Y para la restricción inferior, he establecido 2 restricciones 1. con la restricción inferior de la vista principal a la restricción inferior de la vista. 2. con la restricción inferior de la vista principal a la restricción superior de la vista. Ahora, en la acción del usuario, solo muestro ocultar vista con animación. Entonces, cuando la vista se muestra en la pantalla y la aplicación pasa a segundo plano, la restricción de la vista se altera automáticamente y la vista se oculta. Este problema solo ocurre en dispositivos iOS 13.

Traté de actualizar sus restricciones en viewWillAppear () pero en iOS 13 tampoco se llama a viewWillAppear de ViewControllers cuando la aplicación se activa desde el fondo. Además, no creo que sea una buena idea actualizar las restricciones.

Storyboard

Archivo de clase

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()
            }
        }
    }
}

No quiero que mis restricciones se cambien o actualicen cuando el estado de la aplicación cambie de primer plano a segundo plano y viceversa.

Por favor, ayúdame con lo mismo.

TIA

Rajat Mishra
fuente
1
Está mezclando restricciones con configuraciones de marco explícitas, lo que generalmente generará problemas. No está muy claro lo que quiere ... Cuando se carga su vista, desea contentViewcolocarla debajo de la parte inferior (por lo que está "fuera de la pantalla"), luego desea animarla a la vista ... Luego, la aplicación pasa al fondo , y desea que la vista se siga mostrando cuando la aplicación vuelva al primer plano? No hay nueva animación?
DonMag
Si. Solo quiero así. En realidad, el código que he escrito en viewWillAppear () que se ejecuta en la acción del usuario. Pero para fines de explicación, he creado una demostración.
Rajat Mishra
Suponiendo que la posición / tamaño de la animación funciona correctamente solo con restricciones (sin .frame = ...declaraciones explícitas ), entonces su código debería funcionar bien. ViewDidLoad()debería no ser llamado cuando las transiciones de aplicaciones de fondo a primer plano, a menos que tenga algún otro código que se ejecuta en ese evento.
DonMag

Respuestas:

6

También se reunió este problema. Noté que las restricciones siguen restableciéndose en caso de que no estén marcadas Installeden Interface Builder. Entonces, como solución, mantenga todas las restricciones Installeden IB y cambie el isActiveestado solo en el código.

ingrese la descripción de la imagen aquí

Brigadir
fuente
En realidad, esto no funcionó para mí, porque si lo configuro isActiveen falso, cuando la aplicación pasa a segundo plano y vuelve, volverá a estar activa.
Chris Vasselli
2

Puede lograr la solución al establecer la prioridad y voltear los 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
fuente
2

Descubrí que el problema solo ocurre en iOS 13.0 y versiones posteriores. Intente realizar los cambios de restricción en ViewDidLayoutSubviews

      override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
            self.bottomConstraint.isActive = false
            self.topConstraint.isActive = true
    self.view.layoutIfNeeded()
}
Yogeswaran S
fuente
Funcionó a las mil maravillas. Pero, ¿por qué ocurre solo en iOS 13.0? ¿Y por qué no se llama a viewWillAppear?
Suhail
1

La solución que funcionó para mí fue escuchar UIApplication.willEnterForegroundNotificationy establecer isActivetodas las restricciones en este punto.

Esta notificación parece publicarse después de que el sistema (incorrectamente) restablece todas las restricciones a sus estados IB y antes de que la aplicación vuelva a ser visible. Entonces es el momento perfecto para arreglar las restricciones.

Chris Vasselli
fuente
0

si necesita saber "cómo puedo informar cuando las aplicaciones vienen de fondo a primer plano". Debe usar NotificationCenter para enviar una señal a todos. Pero esta no es una buena práctica.

Tal vez pueda decir su objetivo, y podemos darle un enfoque diferente.

Emre Gürses
fuente
0

Bueno, tengo la solución. En realidad, no podemos decir que sea la solución. Acabo de ejecutar el mismo código en dispositivos iOS 13.1 o versiones superiores y el problema desapareció. Entonces, por ahora, puedo decir que este problema solo ocurre en iOS 13.0.

Rajat Mishra
fuente