2013-06-18 11 views
12

Ich versuche, die nächste Seite der Zellen automatisch zu laden und zu laden, wenn der Benutzer zum Ende der UICollectionView scrollt.Weitere Zellen am unteren Rand von UICollectionView laden

Ich kann dies tun, indem Sie eine UIButton in UICollectoinView Fußzeile hinzufügen. Wenn der Benutzer zur Fußzeile scrollt und die Schaltfläche berührt, werden neue Zellen korrekt hinzugefügt. UIButton in der Fußzeile kann erneut zum Hinzufügen weiterer Seiten berührt werden.

Ich habe versucht, es so zu automatisieren, wenn der Benutzer scrollt nach unten, für die richtige Methode, um neue Zellen Zugabe automatisch aufgerufen wird:

- (UICollectionReuseableView *)collectionView: (UICollectionView *)collectionView viewForSupplementaryElementOfKind: (NSString *)kind atIndexPath: (NSIndexPath *) indexPath 
{ 

    // code for headerView 
    // ... 

    // code for footerView 
    MySupplementalFooter *footerView = nil; 
    if ([kind isEqual:UICollectionElementKindSectionFooter]) 
    { 
     footerView = [self.collectionView dequeueReuseableSupplemntaryViewOfKind:kind withReuseIdentifier:@"FooterId" forIndexPath:indexPath]; 
     if (LoadMoreIsEnabled) 
     { 
      footerView.loadMoreFooterButton.setHidden:NO]; 
      [self loadMoreFooterButtonAction]; // calls the method to add cells to the dictionary for cv 
     } else 
     { 
      footerView.loadMoreFooterButton setHidden:YES]; 
     } 

     return footerView; 
    } 
} 

Die loadMoreFooterButtonAction Methode aufgerufen wird, aber die gesamte UICollectionView Rohlingen aus. Aktualisieren der UICollectionView bringt es nicht zurück.

+0

'UICollectionView Rohlinge Bereich führt zur OMG, das war mein Fall, ich übliche Art und Weise mit' willDisplayCell' aber Sammlung Ansicht zurückgesetzt und ist leer (wtf) versucht. Zuletzt implementiert mit 'scrollViewDidScroll'. – SoftDesigner

Antwort

0

Ich nehme an, dass Sie versuchen, etwas wie "unendliches Scrollen" von Desktop-Webseiten, wo Sie mehr Inhalt laden, wenn ein Benutzer auf den unteren Rand einer Seite kommt. Bei iOS ist dies kein häufig verwendetes Design. In der Regel initialisieren Entwickler ihre UITableView- oder UICollectionView mit der absoluten Gesamtzahl der Einträge. Wenn sie Daten über das Netzwerk streamen müssen, laden sie die Daten nach Bedarf asynchron (wenn Zellen oder Ansichten auf dem Bildschirm angezeigt werden) und bis zum Laden des Inhalts wird eine Art temporärer Inhalt angezeigt, z. B. eine leere Ansicht mit einem Drehfeld.

Das heißt, wenn Sie endloses Scrollen in einer Art und Weise wie eine Desktop-Webanwendung ausführen möchten, sollten Sie das UIScrollViewDelegate-Protokoll (oder UICollectionViewDelegate, das eine Obermenge ist) implementieren und auf den Rückruf scrollViewDidScroll: hören. Innerhalb dieses Callbacks durchlaufen Sie die indexPathsForVisibleItems der UICollectionView und überprüfen Sie, ob einer der Indexpfade dem 'letzten' Element in Ihrer Sammlung zugeordnet ist, was darauf hinweist, dass der Benutzer bis zum Ende gescrollt wurde. An diesem Punkt rufen Sie Ihre Logik, um mehr Zeug zu laden.

+43

"Normalerweise initialisieren Entwickler ihre UITableView oder UICollectionView mit der absoluten Gesamtzahl der Einträge." [Bearbeiten] –

5

Ich weiß, dass dies eine alte Frage ist, aber ich werde eine Lösung für zukünftige Antwortsuchende bieten. Normalerweise, wenn ich endlos auf einem UITableView scrollen will, werde ich prüfen, ob die Grenzen der scrollview der tableView sich mit der rect der tableFooterView schneiden. Fußzeilenansichten sind in UICollectionViews etwas komplizierter. Daher erstelle ich am Ende der collectionView ein rect, um zu sehen, ob es sich mit den scrollView-Grenzen überschneidet, und falls dies der Fall ist, lade ich mehr Elemente. Ich habe auch überprüft, dass wir mindestens etwas in der Tabelle haben, also werde ich nicht wild versuchen, mehr zu laden, wenn der Tisch instanziiert.

Hinweis: Ihre Methode more aktualisiert in diesem Fall die Datenquelle sammlungView und hängt die neuen Elemente an. Ihre Methode numberOfItems/sections sollte die neuen Werte widerspiegeln.

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    if (CGRectIntersectsRect(scrollView.bounds, CGRectMake(0, self.collectionView.contentSize.height, CGRectGetWidth(self.view.frame), 40)) && self.collectionView.contentSize.height > 0) 
    { 
     [self more]; 
    } 
} 
+0

Das funktioniert nicht bei allen – c0d3Junk13

+0

Was ist für Sie nicht @ c0d3Junk13 arbeiten? –

+1

Funktioniert gut für mich in meiner Sammlung Ansicht – RyanG

13

In der Tabellenansicht sollten Sie mehr Daten in der Methode willDisplayCell() laden. Bei Sammlungen gibt es kein solches Gegenstück. Aber du kannst das so machen. Ich hoffe es hilft.

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 
    // Other code here ... 

    if (indexPath.item == [self.photos count] - 1) { 
     [self loadPhotos]; 
    } 

    return cell; 
} 

- (void)loadPhotos { 
    [self showLoadingIndicator]; 
    self.operation = [client HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) { 
     [self hideLoadingIndicator]; 

     // Get data 
     NSArray *photosData = responseObject[@"data"]; 
     NSInteger numberOfResults = [photosData count]; 
     NSInteger totalCount = [self.photos count]; 

     if (numberOfResults > 0) { 
      NSMutableArray *indexPaths = [NSMutableArray new]; 

      for (NSInteger i = 0; i < numberOfResults; i++) { 
       Photo *photo = [Photo new]; 
       photo._id = [photoData[@"id"] integerValue]; 
       photo.url = photoData[@"url"]; 

       [self.photos addObject:photo]; 
       [indexPaths addObject:[NSIndexPath indexPathForRow:totalCount + i 
                inSection:0]]; 
      } 

      [self.collectionView performBatchUpdates:^{ 
       [self.collectionView insertItemsAtIndexPaths:indexPaths]; 
      } completion:nil]; 
     }   
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
     [self hideLoadingIndicator]; 
     // Handle error here 
    }]; 

    [self.operation start]; 
} 
+3

Jetzt hat UICollectionView WillDisplayCell Delegate in iOS8. – vampirewalk

+0

Was sollten wir in der loadMoredata-Methode implementieren? – BHUMICA

+0

@Bhumica Ich aktualisierte meine Antwort. Dies ist ein Beispiel mit AFNetworking. – Sukhrob

19

In IOS8 gibt es eine UICollectionViewDelegate Methode willDisplayCell.

func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) { 
    if indexPath.item == (data.count-1) { 
     loadData() 
    } 
} 
+0

wenn ich den unteren Rand der collectionView erreiche, heißt es in Schleife obwohl .. – Mikael

+0

Keine Schleife für mich, funktioniert gut. – benfwirtz

+0

Ich möchte etwas Verhalten Wissen dazu hinzufügen. Wenn der Benutzer nach oben und unten scrollt, obwohl am Ende dieses Abschnitts möglicherweise eine Situation aufgetreten ist, in der loadData() mehrmals aufgerufen wird. Ich habe eine Kontrolle hinzugefügt, wenn loadData() erneut aufgerufen werden kann. IndexPath.item ist jedoch genau die zu verwendende dynamische Referenz. Guter Anruf http://stackoverflow.com/users/2604669/nick-wargnier –

0

Ich konfrontiert Schwierigkeiten beim Umwandeln @ sukhrob's Antwort auf swift für mein Projekt, so hier ist sein Code in Swift 3 für einfaches Kopieren und Einfügen.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     // Other code here ... 
     if indexPath.item == photos.count() - 1 { 
      loadPhotos() 
     } 
     return cell 
    } 

    func loadPhotos() { 
     showLoadingIndicator() 
     operation = client.httpRequestOperation(with: request, success: {(_ operation: AFHTTPRequestOperation, _ responseObject: Any) -> Void in 
      self.hideLoadingIndicator() 
       // Get data 
      let photosData: [Any] = responseObject["data"] 
      let numberOfResults: Int = photosData.count 
      let totalCount: Int = photos.count() 
      if numberOfResults > 0 { 
       var indexPaths = [Any]() 
       var i = 0 
       while i < numberOfResults { 
        let photo = Photo() 
        photo.id = CInt(photoData["id"]) 
        photo.url = photoData["url"] 
        photos.append(photo) 
        indexPaths.append(IndexPath(row: totalCount + i, section: 0)) 
        i 
       } 
       i += 1 

     collectionView?.performBatchUpdates({() -> Void in 
        collectionView?.insertItems(at: indexPaths as? [IndexPath] ?? [IndexPath]()) 
       }) { _ in } 
      } 
     }, failure: {(_ operation: AFHTTPRequestOperation, _ error: Error?) -> Void in 
      self.hideLoadingIndicator() 
      // Handle error here 
     }) 
     operation.start() 
0

können Sie auch Tutorial 1 und 2 verwenden.

Verwandte Themen