UIView: layoutSubviews vs initWithFrame

Cuando subclasss UIView , por lo general UIView todo mi código de initialization y layout en su método init . Pero me han dicho que el código de disposition debe hacerse anulando el layoutSuviews . Hay una publicación en SO que explica cuándo se llama a cada método, pero me gustaría saber cómo usarlos en la práctica.

Actualmente coloco todo mi código en el método init , así:

MyLongView.m

 - (id)initWithHorizontalPlates:(int)theNumberOfPlates { self = [super initWithFrame:CGRectMake(0, 0, 768, 1024)]; if (self) { // Initialization code _numberOfPlates = theNumberOfPlates; UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.frame]; [scrollView setContentSize:CGSizeMake(self.bounds.size.width* _numberOfPlates, self.bounds.size.height)]; [self addSubview:scrollView]; for(int i = 0; i < _numberOfPlates; i++){ UIImage *img = [UIImage imageNamed:[NSString stringWithFormat:@"a1greatnorth_normal_%d.jpg", i+1]]; UIImageView *plateImage = [[UIImageView alloc] initWithImage:img]; [scrollView addSubview:plateImage]; plateImage.center = CGPointMake((plateImage.bounds.size.width/2) + plateImage.bounds.size.width*i, plateImage.bounds.size.height/2); } } return self; } 

Son las tareas habituales: configurar el marco de la vista, inicializar un ivar, configurar una vista de desplazamiento, inicializar UIImages, ubicarlos en UIImageViews, distribuirlos.

Mi pregunta es: ¿cuál de estos debería hacerse en init , y cuál de estos debería hacerse en layoutSubviews ?

Su init debe crear todos los objects, con los datos requeridos. Cualquier marco que pase a ellos en init idealmente debería ser sus posiciones iniciales.

Luego, dentro de layoutSubviews :, cambia los frameworks de todos tus elementos para ubicarlos donde deberían ir. No debe asignarse ni iniciarse en layoutSubviews :, solo el cambio de sus posiciones, tamaños, etc.

En caso de que esté autorizando funciona perfectamente con solo autorizarFlags o autolayout, puede usar init para configurar toda la vista.

Pero en general, debe hacer el layout en las vistas de layout, ya que se invocará cada cambio del marco de vistas y en otra situación, donde se necesita un layout nuevo. A veces, simplemente no conoce el marco final de una vista dentro de init, por lo que debe ser flexible como se menciona, o usar layoutSubviews, ya que hace el layout allí después de que se haya establecido el tamaño final.

Como lo menciona WDUK, todo el código de initialization / creación de object debe estar en su método init o en cualquier lugar, pero no en layoutSubviews.