sketch - constraints priority ios
Problema de rendimiento de reproducción automática de iOS en modo retrato. (3)
Me he encontrado con un problema muy extraño y me preguntaba si alguien podría ayudarme aquí ya que estoy totalmente perdido.
Contexto: estoy desarrollando una aplicación con una jerarquía relativamente simple. Solo unos pocos controladores de vista, pero muchas imágenes de alta resolución. Se presentan en un UIScrollView
con algún texto, etc. Mientras lo probamos en modo retrato, la vista de desplazamiento no se desplazó sin problemas en absoluto. Parecía que la velocidad de fotogramas se redujo a aproximadamente 4-5 fps. Primero pensé que era por las imágenes de alta resolución.
Pero luego puse el iPad en modo horizontal y todo funcionó sin problemas. Dado que tengo un archivo xib separado para retrato y paisaje, pensé que tenía que haber un problema en el retrato-xib. Resultó que no había. Ambos tenían la misma clase VC y, por lo tanto, usaban el mismo código y ambos xibs son casi idénticos, excepto por los tamaños y las posiciones de las vistas.
Para reducir el problema, utilicé TimeProfiler del instrumento para ver qué está causando el problema. Al final resultó que, TimeProfiler mostró algunas llamadas a [NSISEngine optimize]
(activado por NSLayoutConstraint
). En modo retrato, hubo más llamadas y esas llamadas tomaron mucho más tiempo. Más abajo en el árbol, vi que en el modo vertical [NSISEngine optimize]
llamado [NSISEngine fixupIntegralizationViolations]
y en horizontal no lo hizo.
Incluso eliminé todos los controladores de visualización de la aplicación, excepto el rootVC y otro que presenta el rootVC. El vc presentado solo contiene algunas imágenes, botones y algunas animaciones. Tiene solo un xib para ambas orientaciones y está diseñado (como todos los demás) con autolayout.
El diseño funciona como debería en ambas orientaciones y no hay ambigüedades (por lo que puedo decir. Al menos po [[UIWindow keyWindow] _autolayoutTrace]
no muestra ninguna).
Adjunto una captura de pantalla del TimeProfile del proceso de presentación de la vc. Una para retrato y otra para paisaje. Como puede ver, en modo horizontal, las llamadas a [NSISEngine optimize]
toman solo un milisegundo, mientras que en vertical toman más de 3000 ms.
¿Hay alguien que pueda decirme por qué es eso? ¿O tal vez tiene alguna idea de lo que puedo hacer para averiguar cuál es el problema?
Cualquier ayuda sería muy apreciada!
Gracias
Enlace a una versión más grande de la imagen: link
Me encontré con el mismo problema con una vista moderadamente compleja en la que funcionó bien en iPads que no son Retina o en un iPad Retina en modo retrato. En el modo horizontal en un dispositivo Retina, demoró 10 veces más en mostrar una ventana emergente o empujar otra vista en la pila de vistas. Terminé reemplazando el archivo XIB con un loadView codificado a mano en el controlador de vista. Eso parece haber eliminado el problema. El creador de interfaces tiene una tendencia a crear restricciones excesivas, por lo que tenerlo bajo control es clave para un buen rendimiento de diseño automático.
También he abierto un ticket de soporte para este problema.
Actualizar:
Encontré la causa en mi situación. Fue el siguiente conjunto de restricciones:
NSArray *constraints = [NSLayoutConstraint
constraintsWithVisualFormat : @"|[sunLabel][monLabel(==sunLabel)][tueLabel(==sunLabel)][wedLabel(==sunLabel)][thuLabel(==sunLabel)][friLabel(==sunLabel)][satLabel(==sunLabel)]|"
options : 0
metrics : nil
views : labelViewsDictionary];
Especifica que 7 etiquetas dentro de una vista primaria comparten el mismo tamaño y todas amplían el ancho de la vista principal. Creo que la excesiva naturaleza relacional del diseño estaba dando ajustes automáticos, particularmente porque el ancho de la vista principal no era divisible de manera uniforme entre 7.
Para resolverlo, creé una matriz de restricciones que especifican el ancho de cada etiqueta y apliqué esas restricciones. Cuando el dispositivo gira, el ancho del padre cambia, así que retrocedo y ajusto la constante de las restricciones para que sea 1/7 del ancho de la vista principal. Esto ahora funciona bien, el proceso de cargar una ventana emergente ahora toma menos de 300 ms en lugar de 2000 ms.
Presenté una solicitud de soporte técnico con respecto a este problema y finalmente obtuve la respuesta, que probablemente sea un error. Se archiva el informe de error. Esperemos que lo solucionen pronto. Si hay alguna noticia actualizaré esta respuesta.
Tuve el mismo problema ayer en un dispositivo Ipad iOS6.1. Al instrumentar la aplicación, se encontró que el método de correcciónIntegralizationViolations tardaba unos 300 ms cada vez que se llamaba (unas 20 veces, lo que es mucho), lo que hacía que la aplicación fuera absolutamente inútil.
Mi problema fue muy similar al que comenta Jack Cox, pero lo resolví de manera diferente. Mi restricción era:
@ "H: | [allButton] [inStoreButton (== allButton)] [onlineButton (== allButton)] [sortButton (50)] |"
El problema es que la vista principal aquí es el ancho total del paisaje del iPad, por lo que el cálculo de este contraint estaba dando a cada botón este ancho: (1024-50) / 3 = 324.6666667.
Por lo general, esto no es un problema en la reproducción automática, ya que se ocupa de los grandes números flotantes y los redondea correctamente, pero parece que en el iPad iOS6, el redondeo de estos números provoca un error que bloquea la interfaz de usuario. Para solucionarlo todo lo que tenía que hacer es cambiar el orden del botón para tener 52, por lo que cada ancho de botón ahora es: (1024-52) / 3 = 324. Eso es todo. Ahora el método fixupIntegralizationViolations toma alrededor de 1 ms cada vez que se llama.
Lo interesante es que usar 52 le da un ancho no decimal en Paisaje, pero sí da un número decimal en vertical: (768-52) / 3 = 238.666667. Sin embargo, el retrato parece no tener ningún error y la reproducción automática redondea los números correctamente.