2010-12-01 20 views
36

Estoy intentando crear exactamente el mismo efecto que en la aplicación AppStore para ver capturas de pantalla: dentro de una UITableView, tengo subclases personalizadas de UITableViewCell. Uno de ellos está diseñado para mostrar vistas previas de algunos productos, digamos 4 imágenes. Quiero que se muestren de la misma manera que AppStore presenta capturas de pantalla de una aplicación: dentro de UIScrollView horizontal con su UIPageControl adjunto.Horizontal UIScrollView dentro de una UITableViewCell

Así que añadir mi UIScrollView y mi UIPageControl a mi UITableViewCell, al igual que:

@implementation phVolumePreviewCell 
- (id)init { 
    if (self = [super initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kVolumePreviewCellIdentifier]) { 
     [self setAccessoryType:UITableViewCellAccessoryDisclosureIndicator]; 
     [self setSelectionStyle:UITableViewCellSeparatorStyleNone]; 

     previews = [[NSMutableArray alloc] initWithCapacity:4]; 
     for (int i = 0; i < 4; i++) { 
      [previews addObject:@"dummy"]; 
     } 

     scrollView = [[UIScrollView alloc] initWithFrame:CGRectZero]; 
     [scrollView setPagingEnabled:YES]; 
     [scrollView setBackgroundColor:[UIColor grayColor]]; 
     [scrollView setIndicatorStyle:UIScrollViewIndicatorStyleBlack]; 
     [scrollView setShowsHorizontalScrollIndicator:YES]; 
     [scrollView setBounces:YES]; 
     [scrollView setScrollEnabled:YES]; 
     [scrollView setDelegate:self]; 
     [self.contentView addSubview:scrollView]; 
     [scrollView release]; 

     pageControl = [[UIPageControl alloc] initWithFrame:CGRectZero]; 
     [pageControl setNumberOfPages:[previews count]]; 
     [pageControl setBackgroundColor:[UIColor grayColor]]; 
     [self.contentView addSubview:pageControl]; 
     [pageControl release]; 
    } 
    return self; 
} 

(nota: estoy poblando "vistas previas" con datos ficticios aquí, sólo con el fin de tener un [vistas previas conteo] que funciona; quiero ver el indicador de desplazamiento de scrollView solo para fines de prueba, los esconderé más adelante).

Mi problema es que puedo desplazar todo el UITableView que contiene este phVolumePreviewCell (subclase de UITableViewCell), pero no puedo desplazar el UIScrollView. ¿Cómo puedo conseguir esto?

La única información que encontré está allí: http://theexciter.com/articles/touches-and-uiscrollview-inside-a-uitableview.html Pero habla de viejos SDK (a saber, 2.2) y estoy seguro de que hay un enfoque más "reciente" para hacer esto.

Algunas precisiones:

  • que puede desplazarse por el UIScrollView con dos dedos. Eso no es lo que quiero, quiero que se pueda desplazar solo con un dedo.
  • Cuando me desplazo con dos dedos, el TableView aún intercepta los toques y se desplaza un poco hacia arriba o hacia abajo. Me gustaría que el TableView se quede en su posición cuando toco el ScrollView.

Creo que tengo que encontrar la manera de interceptar toques en mi TableView, y si el contacto está en la phVolumePreviewCell (personalizado UITableViewCell subclase), pasarlo a la celda en lugar de manejarlo en el TableView.

Para el registro, mi TableView se crea mediante programación en una subclase UITableViewController:

@interface phVolumeController : UITableViewController <UITableViewDelegate> { 
    LocalLibrary *lib; 
     NSString *volumeID; 
     LLVolume *volume; 
} 

- (id)initWithLibrary:(LocalLibrary *)newLib andVolumeID:(NSString *)newVolumeID; 
@end 

@implementation phVolumeController 

#pragma mark - 
#pragma mark Initialization 

- (id)initWithLibrary:(LocalLibrary *)newLib andVolumeID:(NSString *)newVolumeID { 
    if (self = [super initWithStyle:UITableViewStylePlain]) { 
     lib   = [newLib retain]; 
     volumeID  = newVolumeID; 
     volume  = [(LLVolume *)[LLVolume alloc] initFromLibrary:lib forID:volumeID]; 
     [[self navigationItem] setTitle:[volume title]]; 
    } 
    return self; 
} 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 
    return 1; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 
    return 1; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kVolumePreviewCellIdentifier]; 
    if (cell == nil) { 
     cell = [[[phVolumePreviewCell alloc] init] autorelease]; 
    } 

    [(phVolumePreviewCell *)cell setVolume:volume]; 
    return (UITableViewCell *)cell; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { 
    return kVolumePreviewCellHeight; 
} 

Gracias por cualquier ayuda!

Respuesta

21

He encontrado una solución.

Recrear desde cero un UITableView muy simple (8 filas) e insertar un UIScrollView en la segunda fila, funciona perfectamente. Las vistas de desplazamiento anidado (TableView y ScrollView) se desplazan independientemente como se esperaba. Todo lo que se hizo en un proyecto de prueba de un solo archivo, en AppDelegate.

Así que ... primero pensé "esto podría ser un problema de delegación", así que le dije al scrollView que su delegado era TableView, no mi subclase TableViewCell personalizada. En vano.

Luego, en lugar de recurrir a una subclase de TableViewCell personalizada y limpia que simplemente agrega ScrollView y PageControl, recurrí a la creación de TableViewCell en el método cellForRowAtIndexPath de TableView. Luego, creo un UIScrollView justo después de inicializar TableViewCell, luego lo agrego a TableViewCell, y shazam ... ¡funciona!

Antes:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kVolumePreviewCellIdentifier]; 
if (cell == nil) { 
    cell = [[[phVolumePreviewCell alloc] init] autorelease]; 
} 

[(phVolumePreviewCell *)cell setVolume:volume]; 
// That does the job of creating the cell's scrollView and pageControl 

return (UITableViewCell *)cell 

Después:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kvcPreviewRowIdentifier]; 
if (cell == nil) { 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kvcPreviewRowIdentifier] autorelease]; 

    previewScrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, kvcPreviewScrollViewHeight)]; 
    [previewScrollView setContentSize:CGSizeMake(1000, kvcPreviewScrollViewHeight)]; 
    [[cell contentView] addSubview:previewScrollView]; 

    previewPageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, kvcPreviewScrollViewHeight, tableView.frame.size.width, kvcPreviewPageControlHeight)]; 
    [previewPageControl setNumberOfPages:4]; 
    [[cell contentView] addSubview:previewPageControl]; 
} 

return (UITableViewCell *)cell; 

Cómo viene diablos que cuando creo mi ScrollView de la subclase TVCell, que no juega muy bien; pero cuando creo el scrollView desde el TableView justo después de crear un TVCell "clásico", ¿funciona?

Pude haber encontrado una solución, pero todavía estoy desconcertado por el motivo.

+0

Gracias Cyrille !! El mismo problema aqui. ¡Tu solución me ahorró muchas horas de desesperación! :-) –

+0

Hola, Cyrille: sé que esta es una vieja pregunta de SO, pero me preguntaba si tendrías una aplicación de muestra para esta solución. Gracias .. – Craig

+0

@Craig: no hay aplicación de muestra, lo siento. Este código ha evolucionado desde entonces y ya no lo uso. Pero realmente, todo el código que necesita para reproducir esta situación está aquí en mis publicaciones. – Cyrille

Cuestiones relacionadas