2010-05-12 10 views
11

Agregué un UITableView como subvista a una clase UIView personalizada en la que estoy trabajando. Sin embargo, noté que siempre que me desplazo por la tabla llama a mis clases layoutSubviews. Estoy bastante seguro de que es el UIScrollview que la tabla está heredando de lo que realmente está haciendo esto, pero quería saber si hay una forma de desactivar esta funcionalidad y, de no ser así, ¿por qué está sucediendo? No entiendo por qué cuando se desplaza una vista de desplazamiento necesita su super visión para diseñar sus subvistas.UIScrollview llamando a superviews layoutSubviews when scrolling?

Código:

@implementation CustomView 
- (id)initWithFrame:(CGRect)frame { 
    if ((self = [super initWithFrame:frame])) { 
     self.clipsToBounds = YES; 

     UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0.0, 15.0, 436.0, 132.0) style:UITableViewStylePlain]; 
     tableView.dataSource = self; 
     tableView.delegate = self; 
     tableView.separatorStyle = UITableViewCellSeparatorStyleNone; 
     tableView.backgroundColor = [UIColor clearColor]; 
     tableView.showsVerticalScrollIndicator = NO; 
     tableView.contentInset = UIEdgeInsetsMake(kRowHeight, 0.0, kRowHeight, 0.0); 
     tableView.tag = componentIndex; 

     [self addSubview:tableView]; 
     [tableView release]; 
    } 
    return self; 
} 
- (void)layoutSubviews { 
    // This is called everytime I scroll the tableview 
} 

@end 

+0

Pero dime, ¿por qué lo haces de esa manera ¿Por qué estás agregando vista de tabla a vista personalizada? – Manjunath

+0

Larga historia, estoy creando un PickerView personalizado que permite una selección múltiple y tiene un tamaño diferente al estándar. Básicamente muestra un fondo PickerView transformado con una tabla clara en la parte superior – marchinram

+0

¿Has mirado esto? El chico parece tener el problema opuesto, en ese layoutSubviews IS NOT called. También mencionó una solución, que si la inviertes, podría funcionar para ti. :) http://stackoverflow.com/questions/728372/when-is-layoutsubviews - llamado – Kalle

Respuesta

2

Sí, un UIScrollView hace llamar layoutsubviews cada vez que se desplaza. Podría haber jurado que esto fue declarado en la documentación en alguna parte, pero supongo que no.

De todas formas, la idea predominante de esto es que un UIScrollView debe layout sus cosas para que las vistas que actualmente no se pueden ver no debe ser expuesto. A medida que los usuarios se desplazan en la vista de desplazamiento, deben agregar y quitar las subvistas según sea necesario. Supongo que esto es lo que TableViews usa para poner en cola celdas de tabla que se ocultan.

¿Hay alguna razón por la que le importa si se llama a layoutsubviews o no?

+0

no, yo estaba corriendo un cierto código de allí que no debería haber estado en funcionamiento, que tiene sentido que establece subvistas cuando hay cambio de posición en el ScrollView – marchinram

+2

Tiene usted razón, pero el verdadero problema es que el desplazamiento de una vista de desplazamiento desencadena 'layoutSubviews' también en su * supervista *, que puede ser costoso e innecesario. Sospecho que es un efecto secundario de cambiar los límites de la vista de desplazamiento, pero bien podría ser solo un error. – Costique

0

No estoy seguro de entender su problema correctamente, pero cuando se desplaza un tableview que elimina las células que no se muestran de la memoria y los carga de nuevo cuando se desplazan de nuevo en la visibilidad (las celdas se asignan a pedido, solo las visibles), de hecho haciendo lo que parece estar describiendo.

1

UITableView al menos parece que el diseño de su supervista. Este comportamiento puede ser problemático si tiene un método layoutSubviews que puede ser costoso (por ejemplo, si llama a algunos JavaScript).

La solución rápida es añadir una vista secundaria intermediaria que impide la vista de desplazamiento de la disposición de su supervista. En cambio, distribuirá la subvista intermedia.

Esto podría ser algo imperfecta pero debería funcionar para la mayoría de los casos:

Supongamos UIView * intermediateView se define como una variable de instancia:?

-(id) initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame: frame]; 
    if (self) 
    { 
     UIScrollView * theScrollView; // = your scroll view or table view 
     intermediateView = [[[UIView alloc] initWithFrame:CGRectZero] autorelease]; 
     // Ensures your intermediate view will resize its subviews. 
     intermediateView.autoresizesSubviews = YES; 

     // Ensure when the intermediate view is resized that the scroll view 
     // is given identical height and width. 
     theScrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | 
             UIViewAutoresizingFlexibleHeight; 
     [intermediateView addSubview: theScrollView]; 

     // Ensure the frame of the scroll view is exactly the bounds of your 
     // intermediate view. 
     theScrollView.frame = bottomContainerView.bounds; 
     [self addSubview: intermediateView]; 
    } 
    return self; 
} 

-(void) layoutSubviews 
{ 
    intermediateView.frame = CGRectMake(0, 50, 42, 42); // replace with your logic 
}