safe remove react bar ios iphone swift iphone-x

ios - remove - safeAreaInsets en UIView es 0 en un iPhone X



safe area react native (7)

Estoy actualizando mi aplicación para adaptarla para iPhone X. Todas las vistas funcionan bien ahora, excepto una. Tengo un controlador de vista que presenta una vista UIV personalizada que cubre toda la pantalla. Antes de usar UIScreen.main.bounds para averiguar el tamaño de la vista antes de que se hiciera todo el diseño (lo necesito para colocar el ItemSize correcto para una collectionView). Pensé que ahora podía hacer algo como UIScreen.main.bounds.size.height - safeAreaInsets.bottom para obtener el tamaño adecuado para usar. El problema es que safeAreaInsets devuelve (0,0,0,0) probando un iPhone X (Simulador). ¿Algunas ideas? En otras vistas, obtengo los números correctos para safeAreaInsets.

¡Gracias!


El método viewDidAppear (_ :) del controlador de vista de contenedor que extiende el área segura de su controlador de vista secundario integrado para tener en cuenta las vistas en.

Realice sus modificaciones en este método porque las inserciones de área segura para una vista no son precisas hasta que la vista se agrega a una jerarquía de vistas.

override func viewDidAppear(_ animated: Bool) { if (@available(iOS 11, *)) { var newSafeArea = view.safeAreaInsets // Adjust the safe area to accommodate // the width of the side view. if let sideViewWidth = sideView?.bounds.size.width { newSafeArea.right += sideViewWidth } // Adjust the safe area to accommodate // the height of the bottom view. if let bottomViewHeight = bottomView?.bounds.size.height { newSafeArea.bottom += bottomViewHeight } // Adjust the safe area insets of the // embedded child view controller. let child = self.childViewControllers[0] child.additionalSafeAreaInsets = newSafeArea } }


Me he encontrado con el mismo problema. En mi caso, la vista que estoy insertando se dimensionaría correctamente después de llamar a view.layoutIfNeeded() . Los view.safeAreaInsets se configuraron después de esto, pero solo el valor top era correcto. El valor inferior todavía era 0 (esto en un iPhone X).

Al tratar de averiguar en qué punto se configuran correctamente los conjuntos de safeAreaInsets , agregué un punto de interrupción en el método de safeAreaInsetsDidChange() de safeAreaInsetsDidChange() la vista safeAreaInsetsDidChange() . Esto se llamaba varias veces, pero solo cuando vi CALayer.layoutSublayers() en el backtrace el valor se había establecido correctamente.

Por lo tanto, he reemplazado view.layoutIfNeeded() por la contraparte de view.layer.layoutIfNeeded() , lo que dio como resultado que safeAreaInsets se configurara correctamente de inmediato, por lo que resolví mi problema.

TL; DR

Reemplazar

view.layoutIfNeeded()

por

view.layer.layoutIfNeeded()


Recientemente tuve un problema similar en el que las inserciones de área segura están regresando (0, 0, 0, 0) tan pronto como se desencadena viewDidLoad. Parece que se configuran fraccionadamente más tarde que el resto de la vista cargando.

Lo redondeé al anular viewSafeAreaInsetsDidChange y hacer mi diseño en ese lugar:

override func viewSafeAreaInsetsDidChange() { // ... your layout code here }


También me he topado con este problema al intentar subir las vistas para dar paso al teclado en el iPhone X. Los SafeAreaInsets de la vista principal son siempre 0, aunque sé que las subvistas se han presentado en este punto como la pantalla ha sido dibujado Una solución que encontré, como se mencionó anteriormente, es obtener KeyWindow y verificar sus inserciones de área segura en su lugar.

Obj-C:

CGFloat bottomInset = [UIApplication sharedApplication].keyWindow.safeAreaInsets.bottom;

Rápido:

let bottomInset = UIApplication.shared.keyWindow?.safeAreaInsets.bottom

Luego puede usar este valor para ajustar restricciones o ver marcos según sea necesario.


También tiene la opción, si usa el diseño automático, de mantener su restricción inferior para view.safeAreaLayoutGuide.bottomAnchor ! Su diseño estará constantemente actualizado sin necesidad de observar los cambios.


Tengo una vista que es una subvista dentro de otra vista. Descubrí que no puedo obtener SafeAreaInsets correctamente, siempre devuelve 0, en esa vista en iPhoneX, incluso si lo puse en layoutSubviews. La solución final es utilizar la siguiente extensión de UIScreen para detectar SafeAreaInsets que pueden funcionar como un encanto.

extension UIScreen { func widthOfSafeArea() -> CGFloat { guard let rootView = UIApplication.shared.keyWindow else { return 0 } if #available(iOS 11.0, *) { let leftInset = rootView.safeAreaInsets.left let rightInset = rootView.safeAreaInsets.right return rootView.bounds.width - leftInset - rightInset } else { return rootView.bounds.width } } func heightOfSafeArea() -> CGFloat { guard let rootView = UIApplication.shared.keyWindow else { return 0 } if #available(iOS 11.0, *) { let topInset = rootView.safeAreaInsets.top let bottomInset = rootView.safeAreaInsets.bottom return rootView.bounds.height - topInset - bottomInset } else { return rootView.bounds.height } } }


Ya encontré la solución: estaba haciendo toda la implementación en el init de la vista. safeAreaInsets tiene el tamaño correcto en layoutSubviews()