36 votes

UIScrollView horizontal dans une UITableViewCell

Je suis en train de créer exactement le même effet que dans l'AppStore application pour l'affichage des captures d'écran: à l'intérieur d'un UITableView, j'ai personnalisé les sous-classes de UITableViewCell de l'. L'un d'eux est conçu pour afficher des aperçus de certains produits, dire 4 images. Je veux leur montrer de la même manière que l'AppStore présente des captures d'écran d'une application : à l'intérieur d'une horizontale UIScrollView avec son attaché UIPageControl.

J'ajoute donc mon UIScrollView et mon UIPageControl à mon UITableViewCell, juste comme ça :

@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;
}

(note: je suis peuplement "aperçus" avec les données factices ici, juste pour avoir un [aperçus comte, qui fonctionne ; je veux afficher le scrollView de défilement de l'indicateur à des fins de test uniquement, je vais cacher plus tard).

Mon problème est que je peut faire défiler toute la UITableView contenant ce phVolumePreviewCell (sous-classe de UITableViewCell), mais je ne peux pas faire défiler la UIScrollView. Comment puis-je y parvenir?

La seule information que j'ai trouvé est ici: http://theexciter.com/articles/touches-and-uiscrollview-inside-a-uitableview.html Mais il parle de vieux Kits de développement logiciel (à savoir 2.2) et je suis sûr qu'il est plus "récent" approche à cet égard.

Quelques précisions :

  • Je peux faire défiler la UIScrollView avec deux doigts. Ce n'est pas ce que je veux, je veux qu'il soit capable de faire défiler avec un seul doigt.
  • Quand j'ai faites défiler avec deux doigts, le TableView encore intercepte la touche de défilement et un peu vers le haut ou le bas. J'aimerais que la TableView à coller à sa position quand je touche la ScrollView.

Je crois que je dois travailler comment intercepter les touches sur mon TableView, et si le contact est sur la phVolumePreviewCell (personnalisé UITableViewCell sous-classe), le passer à la cellule au lieu de la manipulation sur la TableView.

Pour la petite histoire, ma TableView est créé par programmation dans un UITableViewController sous-classe:

@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;
}

Merci pour toute aide!

21voto

Cyrille Points 11109

J'ai trouvé une solution de contournement.

De recréer à partir de zéro un très simple UITableView (8 lignes), et l'insertion d'un UIScrollView dans la deuxième ligne, fonctionne parfaitement. Imbriquée de défilement des vues (la TableView et la ScrollView) de défilement indépendamment, comme prévu. Tout ce qui a été fait dans un seul fichier de projet de test, dans l'AppDelegate.

Alors... tout d'abord j'ai pensé: "cela pourrait être une délégation de problème", alors j'ai dit à la scrollView que son délégué, le TableView, pas ma coutume TableViewCell sous-classe. En vain.

Alors, au lieu de recourir à une coutume, propre TableViewCell sous-classe qui ajoute juste la ScrollView et le contrôle pagecontrol, j'ai eu recours à la création d'une plaine TableViewCell dans la TableView de cellForRowAtIndexPath: la méthode. Ensuite, j'ai créer un UIScrollView juste après l'initialisation de la TableViewCell, puis l'ajouter à la TableViewCell, et shazam... ça marche!!!

Avant:

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

Aprè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;

Comment diable vient que quand je créer mon scrollView de la TVCell sous-classe, il ne joue pas gentil, mais quand je créer la scrollView de la TableView juste après la création d'un "classique" TVCell, ça marche?

J'ai peut-être trouvé une solution, mais je suis toujours intrigué par la raison.

0voto

Andrew Ebling Points 1994

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X