2012-10-01 9 views
10

Ich verwende eine UICollectionView programmgesteuert.UICollectionView mit FlowLayout nicht scrollen, wenn Abschnittseinfügungen

Ich habe festgelegt es Rahmen ist wie folgt:

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

Mein UICollectionViewFlowLayout hat einen Einschub Abschnitt eingestellt, wie:

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

ich auch nur 1 Schnitt haben.

Ich habe die Höhe auf 3000 eingestellt, um zu sehen, ob die Ansicht der Sammlung scrollen würde, aber nicht. Ich setze es darauf, da die Ansicht der Sammlung nicht nach oben oder unten scrollt, wenn ich neue Objekte einfüge.

UICollectionView ist von einem UIScrollView abgeleitet, was bedeutet, dass ich die Inhaltsgröße der Bildlaufansicht zurücksetzen kann. Würde das richtig funktionieren?

Das einzige Problem ist, dass dies funktionieren würde, wenn ich die Größen aller Elemente einschließlich der Anzahl der Elemente in jeder Zeile kenne.

Wenn jedes Element eine andere Größe hätte, wie würde ich die Größe jeder Zeile herausfinden? Ich würde das brauchen, um alle Reihengrößen hinzuzufügen und die Höhe der Inhaltsgröße von self.collectionView zu erhöhen.

EDIT

Auch über meinen Vorschlag, den Inhalt Größe zurückzusetzen, funktioniert nicht richtig! Ich habe Folgendes versucht, wenn ich meine Sammlungsansicht aktualisiere:

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

Dies ist sehr hässlich obwohl. Das liegt daran, dass angenommen wird, dass alle meine Bilder eine Größe von 200x200px haben, was 3 Bildern pro Zeile entspricht (daher die Teilung durch 3).

Darüber hinaus, auch mit der +300, die ich habe, die letzte Zeile kann ich nur etwa 3/4 davon und nicht alles davon sehen. Ich muss mehr scrollen und ich werde es sehen können, aber es geht wieder zurück zu 3/4. Die Art wie die zu aktualisierende Rolle, in der sich die Ansicht nur bewegt, wenn Sie sie ziehen und wenn Sie sie verlassen, springt sie zurück, wo sie war. Warum passiert dies? Ist es nur so, dass Apple UICollectionView so schlecht entworfen hat? Das ist ein bisschen lächerlich ... UITableViews passt ihren Bildlauf automatisch an ihren Inhalt an.

Antwort

13

Bei der Beantwortung einiger Ihrer anderen Fragen zu UICollectionView habe ich dieses Demo-Projekt erstellt, und es scrollt gut, also weiß ich nicht, welches Problem Sie haben. Das einzige, was ich tun musste, um die letzte Zeile vollständig sichtbar zu machen, war die Größe des unteren Insert auf 90 zu erhöhen. Ich fügte auch eine Completion-Methode zu performBatchUpdates hinzu: completion: um automatisch zu scrollen, so dass das zuletzt hinzugefügte Element sichtbar ist (Beachten Sie, dass ich einige zusätzliche Elemente mithilfe von performSelector hinzufügen; withObject: afterDelay :). Meine Bilder sind 48 x 48, und ich stelle meine Sammlungsansicht auf die Grenzen der Ansicht meines Controllers ein. Hier ist der Code, so dass Sie es vergleichen, was Sie haben:

@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

Einstellen der Höhe des UICollectionView-3.000 Ihre Scrolling Problem verschlimmern. Wenn die UICollectionView 3000 Pixel groß ist, dann muss sie nur scrollen, wenn sie mehr als 3000 Pixel Inhalt enthält. Sie sollten es auf die Höhe der Ansicht einstellen, in der es enthalten ist (genauso wie die Breite).

AFAIK setzen das sollte auch nicht die contentSize direkt, stattdessen müssen Sie die - (CGSize)collectionViewContentSize Methode in einer Unterklasse von UICollectionViewLayout, außer Kraft zu setzen, aber im Allgemeinen sollten Sie den Inhalt ändern müssen Größe für den normalen Gebrauch nicht.

Ich bin nicht ganz klar auf, was Ihr Problem ist - ist es, dass, wenn Sie mehr als einen Bildschirm im Wert von Artikeln hinzufügen können Sie nicht scrollen?

+0

Das war die Lösung für mich. Ich habe ein benutzerdefiniertes Flow-Layout verwendet, das die vertikalen Lücken zwischen Elementen in einem mehrspaltigen Layout entfernt hat. Ich bekam nur ungefähr die Hälfte der Gegenstände, bis ich es tat, wie Simon es vorgeschlagen hatte. Ich vermute, der Grund, warum ich das Problem hatte, ist, dass die Anzahl der abgefragten Artikel auf einem Standard-Layout basiert. –

2

Ich habe das gleiche Problem, weil ich die Elemente meiner CollectionView (d. H. Es DataSource) in der viewWillAppear-Methode initialisiert wurde.

Ich füge endlich nur eine [self.collectionView reloadData]; hinzu und es funktioniert gut!

Vielleicht sind Sie im selben Fall.

Verwandte Themen