Resumen: ¿Cómo debe saber el UIViewController
el tamaño de su instancia de UIView al inicializar esa vista?Dónde determinar el tamaño de UIView
El método de inicialización dedicado para una UIView es el método initWithFrame:(CGRect)frame
. Esto establece el marco para el UIView recién creado. Este método podría invocarse desde el método loadView UIViewController's
, si se solicita la vista del controlador de vista. La documentación de UIViewController
estados con respecto a la subclasificación y la vista de tamaño:
Al crear los puntos de vista de la jerarquía de vista , siempre se debe establecer las propiedades de tamaño automático de sus puntos de vista. Cuando se muestra un controlador de vista en pantalla, su vista raíz es típicamente redimensionada para ajustarse al espacio disponible, que puede variar dependiendo de la orientación actual de la ventana y la presencia de otros elementos de la interfaz tales como la barra de estado.
Por lo tanto, la instancia UIViewController
debe establecer esas propiedades. Hasta ahora todo bien, el UIViewController
hasta ahora no tiene que saber qué tan grande es o será su vista.
Cuando se solicita la vista de UIViewController
y la propiedad de vista es nula, se invoca el método loadView del controlador de vista. Ahora hay un problema, porque el UIView
necesita inicializarse, pero el controlador de vista aún no sabe qué tamaño debe tener la vista. ¿Qué tan grande debe inicializar esa vista? ¿Dónde en el código determina el tamaño de la vista?
Se podría iniciar la vista con un rect cero (CGRectZero
):
- (void)loadView {
self.view = [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
}
Y dejar que la persona que llama establece el marco de vista, así:
UIViewController *viewController = [[MyUIViewController alloc] init];
// next two lines are normally combined, but for clarity they are not now
UIView *view = viewController.view;
view.frame = CGRectMake(0, 0, 200, 200);
Esto pide la vista desde el controlador de vista (viewController.view), y así carga su vista con el método loadView. Este método loadView inicializa la vista con un CGRectZero
. Luego, la persona que llama establece su fotograma (view.frame = ...)
Lo que sucede es que la propiedad del fotograma en la vista se establece dos veces, posiblemente causando incluso más trabajo doble si su UIView
personalizado está haciendo un diseño avanzado en el método setFrame (colocando y redimensionando subvistas por ejemplo). Puede evitar esto creando un método de inicialización dedicado para el UIViewController
que ya le pide a la persona que llama para un CGRect, que almacenaría en un ivar. En el momento en que se llama al método loadView, usa este ivar para crear la vista.
¿Cuál es el mejor camino para ir aquí? ¿Configurando el marco de la vista dos veces (inicializando con CGRectZero
, y estableciendo luego), o dando al UIViewController
un nuevo método de inicialización con un CGRect (y dándole así una propiedad de marco)? ¿O me estoy perdiendo algo y hay otras posibilidades?
método init UIView en realidad llama initWithFrame con un rect – drvdijk
cero Me he dado cuenta ahora, mientras se aplica una transformación a una vista, la se llama a layoutSubviews. Teniendo en cuenta que estoy aplicando la transformación en el método touchesMoved de la controladora de vista, no sería recomendable realizar mucho trabajo en layoutSubviews ... – drvdijk
'layoutSubviews' se llama perezosamente (después de' setNeedsLayout') y solo una vez por un montón de cambios . Por lo tanto, es el mejor lugar para realizar costosos redimensionamientos. –