2010-09-18 6 views
7

Publicación por primera vez en desbordamiento de pila.UIView y AutoresizingMask ignoraron

He pasado horas recorriendo muchas búsquedas de Google y, en este punto, prácticamente he memorizado los documentos de referencia de clase UIView y UIViewController. No importa lo que haga, mi aplicación está ignorando mis esfuerzos para cambiar el tamaño de mis puntos de vista sobre el cambio de orientación (o cualquier otra modificación de tamaño de cuadro).

No hay plumillas ni xibs involucrados; Estoy construyendo todos mis puntos de vista y controladores de vista programáticamente, y ellos (los controladores de vista) son todas las subclases de una de las tres subclases UIViewController personalizadas que he creado. Estos súper clases tienen las siguientes líneas en su loadView: método ...

[self setView:[[[UIView alloc] initWithFrame:[self viewFrame]] autorelease]]; 
[[self view] setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)]; 
[[self view] setAutoresizesSubviews:TRUE]; 

En todos los métodos setter adecuados (donde quiera que añadir una vista secundaria en otras palabras) estoy repitiendo las etapas de aplicar la autoresizingMask. Parece que no importa lo que haga, el resultado siempre es el mismo: hago clic en compilar, hago clic en depuración, espero a que la aplicación se inicie, gire el dispositivo y ¡listo! La vista gira pero no cambia de tamaño en absoluto.

¿Qué me falta aquí? Probablemente es algo obvio que simplemente no estoy viendo. Cualquier ayuda es realmente apreciada, gracias de antemano.

Respuesta

33

Bueno, efectivamente, fue mi culpa.

Lección número uno:usted no está haciendo ningún favor al permanecer despierto toda la noche tratando de arreglar el código roto. ¡Descansar un poco! ¡Bebe más agua! Probablemente empeorarás las cosas si sigues tratando de obligar a tu cerebro a realizar una compleja estrategia algorítmica y lógica después de la hora de acostarse.

Resulta que tenía un UIView deshonesto hacia la parte inferior de la jerarquía de vista que no tenía la propiedad de autoevaluación establecida en absoluto. Pensé que había revisado todo, pero resultó que me perdí una. (¡Solo una pequeña vista, y una toma de todo el día!)

Puedo decir para cualquiera que venga después con una frustración similar, que Autoresizing sí funciona como está documentado. Si piensas que "algo no está siendo llamado", probablemente estés mirando en el lugar equivocado. Además, las constantes de enumeración UIViewAutoresizingMask no se usan exactamente como en Interface Builder. En IB, usted "bloquea" los márgenes, mientras que al establecerlos mediante programación, los márgenes bloqueados se suponen por defecto y usted los "desbloquea" configurándolo como "Flexible". Por ejemplo, establecer solo los bits FlexibleWidth y FlexibleHeight es equivalente a habilitar todas las opciones de ajuste automático en IB. Al agregar cualquiera de las máscaras de margen (es decir, UIViewAutoresizingFlexibleLeftMargin), está "deseleccionando" la opción de aumento de tamaño de margen correspondiente en IB. (He visto muchos otros mensajes que parecían ser un gran punto de confusión para algunos).

Durante mi investigación, sin embargo, noté que no parece haber ningún tipo de evento, mensaje, notificación o de otro modo cuando se cambia el tamaño de una UIView, ya sea de forma automática o no. Si bien no es necesario para cambiar el tamaño de subViews, sería bueno saber cuándo está sucediendo en la situación en la que desea hacer que scrollView o tableView se desplacen en caso de que cambie el tamaño de su marco. Sé que uno puede hacer esto fácilmente cuando aparece el teclado, porque hay un sistema de notificación así como los métodos TextFielddelegate. Así que tal vez un tema para otra publicación ...

De todos modos, ¡gracias a todos los que participan en StackOverflow!

+2

Overriding -setFrame: es una forma bastante confiable de ver que una vista ha cambiado de tamaño. – aksommerville

+0

¡Oh sí, claro! Utilizo esa técnica todo el tiempo cuando la depuración retiene el recuento, pero a menudo omito hacerlo en otras situaciones como esta. (Es curioso lo evasivo que puede ser lo obvio). Para aclarar su comentario para los demás, esto se refiere a reemplazar -setFrame para escupir algún NSLog que le indique el nombre de la vista y algunos valores de cuadro. (No olvides llamar a la implementación de super si pruebas esto.) – quickthyme

+0

Aparte de eso, no usaría ese método para nada más. También me inclino por desactivar la anulación antes de liberar el código como producción. – quickthyme