2012-10-01 2 views
10

J'utilise un UICollectionView par programmation.UICollectionView avec FlowLAyout ne défile pas lors de la définition des insertions de section

Je l'ai établi est cadre comme suit:

UICollectionView *collectionView = [[UICollectionView alloc] initWithFrame:CGRectMake(0, 100, self.view.frame.size.width, 3000) collectionViewLayout:flowLayout]; 

Mon UICollectionViewFlowLayout a un encart de section définie comme:

flowLayout.sectionInset = UIEdgeInsetsMake(20.0, 20.0, 100.0, 20.0); 

Je n'ai aussi 1 section.

J'ai défini la hauteur à 3 000 pour voir si la vue de collection défilerait mais ce n'est pas le cas. Je le règle car la vue de collection ne semble pas défiler vers le haut ou vers le bas lorsque j'insère de nouveaux éléments.

UICollectionView est sous-classé à partir d'un UIScrollView, ce qui signifie que je peux continuer à réinitialiser la taille du contenu de la vue défilante. Cela fonctionnerait-il correctement?

Le seul problème est que cela fonctionnerait si je connaissais la taille de tous les éléments, y compris le nombre d'éléments sur chaque ligne.

Si chaque article avait une taille différente, comment pourrais-je connaître la taille de chaque rangée? J'aurais besoin de cela pour ajouter toutes les tailles de lignes et augmenter la hauteur de la taille du contenu de self.collectionView.

EDIT

Même ma suggestion ci-dessus, la réinitialisation de la taille du contenu, ne fonctionne pas correctement! J'ai essayé ce qui suit lors de la mise à jour de ma vue de collection:

int numberOfRows = self.dataArray.count/3; 
self.collectionView.contentSize = CGSizeMake(self.view.frame.size.width, (numberOfRows * 200) + 300); 

Ceci est très moche cependant. C'est parce qu'il suppose que toutes mes images sont de taille 200x200px, ce qui correspond à 3 images par rangée (d'où la division par 3).

En outre, même avec le +300 que j'ai, la dernière rangée, je ne vois que les 3/4 et pas tout. Je dois faire défiler plus et je serai capable de le voir mais il remonte encore au 3/4. C'est un peu comme le parchemin à rafraîchir, où la vue ne bouge que si vous le faites glisser et quand vous le quittez, il revient à l'endroit où il se trouvait. Pourquoi cela arrive-t-il? Est-ce juste que Apple a conçu UICollectionView si mal? C'est un peu ridicule ... UITableViews ajuste automatiquement leur défilement en fonction de leur contenu.

Répondre

13

En répondant à certaines de vos autres questions sur UICollectionView, j'ai créé ce projet de démonstration, et il défile très bien, donc je ne sais pas quel problème vous avez. La seule chose que je devais faire pour rendre la dernière rangée entièrement visible était d'augmenter la taille de l'encart inférieur à 90. J'ai également ajouté une méthode d'achèvement à performBatchUpdates: completion: pour défiler automatiquement de sorte que le dernier élément ajouté soit visible (remarquez que j'ajoute des éléments supplémentaires en utilisant performSelector; withObject: afterDelay :). Mes images sont 48x48, et je viens de définir ma vue de collection aux limites de la vue de mon contrôleur. Voici le code pour que vous puissiez le comparer à ce que vous avez:

@interface ViewController() <UICollectionViewDataSource, UICollectionViewDelegateFlowLayout> { 
NSMutableArray *newData; 
} 
@property (nonatomic, retain) UICollectionView *collectionView; 
@property (nonatomic, retain) NSMutableArray *results; 
@end 

@implementation ViewController 

- (void)viewDidLoad { 
    self.results = [NSMutableArray array]; 
    int i = 11; 
    while (i<91) { 
     UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"New_PICT00%d.jpg",i]]; 
     [self.results addObject:image]; 
     i++; 
    } 

    UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init]; 
    //flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal; 

    self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:flowLayout]; 
    self.collectionView.dataSource = self; 
    self.collectionView.delegate = self; 
    self.view.backgroundColor = [UIColor blackColor]; 
    [self.view addSubview:self.collectionView]; 
    [self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"Cell"]; 
    //[self.collectionView registerClass:[RDCell class] forCellWithReuseIdentifier:@"myCell"]; 
    [self.collectionView reloadData]; 

    [self performSelector:@selector(addNewImages:) withObject:nil afterDelay:3]; 
} 

-(void)addNewImages:(id)sender { 
    newData = [NSMutableArray array]; 
    int i = 102; 
    while (i<111) { 
     UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"New_PICT0%d.jpg",i]]; 
     [newData addObject:image]; 
     i++; 
    } 
    [self addNewCells]; 
} 

-(void)addNewCells { 
    NSMutableArray *arrayWithIndexPaths = [NSMutableArray array]; 
    [self.collectionView performBatchUpdates:^{ 
     int resultsSize = [self.results count]; 
     [self.results addObjectsFromArray:newData]; 
     for (int i = resultsSize; i < resultsSize + newData.count; i++) 
      [arrayWithIndexPaths addObject:[NSIndexPath indexPathForRow:i inSection:0]]; 
     [self.collectionView insertItemsAtIndexPaths:arrayWithIndexPaths]; 
    } 
    completion: ^(BOOL finished){ 
     [self.collectionView scrollToItemAtIndexPath:arrayWithIndexPaths.lastObject atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES]; 
    }]; 
} 


- (NSInteger)collectionView:(UICollectionView *)view numberOfItemsInSection:(NSInteger)section { 
    return [self.results count]; 
} 

- (NSInteger)numberOfSectionsInCollectionView: (UICollectionView *)collectionView { 
    return 1; 
} 

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath]; 
    //cell.iv.image = [self.results objectAtIndex:indexPath.row]; 
    cell.backgroundColor = [UIColor colorWithPatternImage:[self.results objectAtIndex:indexPath.row]]; 
    return cell; 
} 


- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath { 
    UIImage *image = [self.results objectAtIndex:indexPath.row]; 
    return CGSizeMake(image.size.width, image.size.height); 
} 

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout*)collectionViewLayout insetForSectionAtIndex:(NSInteger)section { 
    return UIEdgeInsetsMake(10, 10, 90, 10); 
} 

- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath { 
    NSLog(@"Selected Image is Item %d",indexPath.row); 
} 
9

Réglage de la hauteur du UICollectionView-3000 fera votre problème de défilement pire. Si le UICollectionView fait 3000 pixels de haut, il n'aura besoin de faire défiler que s'il contient plus de 3000 pixels de contenu. Vous devez le définir à la hauteur de la vue dans laquelle il est contenu (identique à la largeur).

AFAIK l'appareil ne doit pas non plus directement le contentSize, au contraire, vous devez remplacer la méthode - (CGSize)collectionViewContentSize dans une sous-classe de UICollectionViewLayout, mais vous en général ne devrait pas avoir besoin de changer la taille du contenu pour des utilisations normales.

Je ne suis pas tout à fait clair sur ce qu'est votre problème - est-ce que vous ne pouvez pas faire défiler quand vous ajoutez plus qu'une valeur d'écran des éléments?

+0

C'était la solution pour moi. J'utilisais une disposition de flux personnalisée qui supprimait les écarts verticaux entre les éléments d'une disposition multi-colonnes. Je n'obtenais que la moitié des articles jusqu'à ce que je le fasse comme Simon l'a suggéré. Je soupçonne la raison pour laquelle j'ai eu le problème est que le nombre d'éléments demandés est basé sur une mise en page standard. –

2

J'ai rencontré le même problème car j'ai initialisé les éléments de mon collectionView (c'est-à-dire c'est DataSource) dans la méthode viewWillAppear.

Enfin, j'ajoute juste un [self.collectionView reloadData]; et ça marche très bien!

Peut-être que vous êtes dans la même affaire.

Questions connexes