2010-02-25 5 views
12

Je suis confronté à un problème simple mais fastidieux. Ce que j'essaie de faire est de rendre un UITableView à la page comme un UIScrollView mais activer la pagination ne m'aide pas tellement parce que je ne peux pas définir la taille de la page afin que la table défile exactement de sa hauteur .10 ou 11 ... 20 et ainsi de suite. Ce que j'aimerais à la place, c'est qu'aucune cellule ne reste clippée au-dessus ou en dessous de la vue quand je défile (donc pagination) sans avoir une sorte de plage fixe de cellules affichées.Taille de page UITableView lorsque la pagination est activée

Merci beaucoup

Répondre

13

simple mais efficace:

- (void)scrollViewDidEndDecelerating:(UITableView *)tableView { 
      int tomove = ((int)tableView.contentOffset.y%(int)tableView.rowHeight); 
      if(tomove < tableView.rowHeight/2) [tableView setContentOffset:CGPointMake(0, tableView.contentOffset.y-tomove) animated:YES]; 
      else [tableView setContentOffset:CGPointMake(0, tableView.contentOffset.y+(tableView.rowHeight-tomove)) animated:YES]; 
    } 

    - (void)scrollViewDidEndDragging:(UITableView *)scrollView willDecelerate:(BOOL)decelerate { 
      if(decelerate) return; 

      [self scrollViewDidEndDecelerating:scrollView]; 
    } 
+0

n'a pas vraiment travailler pour moi. De plus, parce que vous utilisez DidEndDecelerating, le code n'est pas appelé quand il n'y a pas de décélération (ie: si la table n'est pas "feuilletée", mais doucement) – pixelfreak

+0

Donc, vous devez ajouter le même code à - (void) scrollViewDidEndDragging :(UIScrollView *) scrollView willDecelerate: (BOOL) décélère si willDecelerate: (BOOL) decelerate est faux – Julien

+0

@Julien Yep, j'ai oublié de coller la seconde méthode. Personne ne l'a remarqué pendant plus d'un an! Thx – maxcanna

16

Plus simple et plus efficace :)

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ 

    if(decelerate) return; 

    [self scrollViewDidEndDecelerating:scrollView]; 
} 


- (void)scrollViewDidEndDecelerating:(UITableView *)tableView { 

    [tableView scrollToRowAtIndexPath:[tableView indexPathForRowAtPoint: CGPointMake(tableView.contentOffset.x, tableView.contentOffset.y+tableView.rowHeight/2)] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
} 
+2

Cette solution a fonctionné parfaitement pour moi, et a fonctionné pour tous les parchemins. L'autre solution était un peu incohérente avec ses résultats ... parfois, elle s'accrocherait en haut de la cellule, d'autres fois non. – codeqi

+0

@codeqi la raison pour laquelle il saute parfois en haut est parce que vous avez probablement un espace entre vos éléments dans le collectioView. Dans ce cas, la méthode indexPathForRowAtPoint renvoie 0,0 - ce qui conduit au début. ;) – Lirik

4

Cela fonctionne comme la pagination réelle:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView 
        withVelocity:(CGPoint)velocity 
       targetContentOffset:(inout CGPoint *)targetContentOffset 
{ 
    int tomove = ((int)targetContentOffset->y % (int)self.tableView.rowHeight); 
    if(tomove < self.tableView.rowHeight/2) 
     targetContentOffset->y -= tomove; 
    else 
     targetContentOffset->y += (self.tableView.rowHeight-tomove); 
} 

et faites ceci au -viewDidLoad:

self.tableView.decelerationRate = UIScrollViewDecelerationRateFast; 
+0

Cela fonctionne presque parfaitement, mais échoue pour les cellules de taille plein écran lorsque vous faites un flip très doux (pas assez d'un flip pour avancer la page). Il déplace instantanément la cellule au lieu de l'animer en douceur. –

5

A partir de k06a's answer, je l'ai affiné un peu il fonctionne plus comme le vrai UITableView paginé. Les différences de comportement sont assez perceptibles avec les lignes du tableau en plein écran. Même un mini-film dans les deux sens devrait faire défiler le tableau vers la page suivante: Je le fais en vérifiant d'abord la vélocité.

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView 
        withVelocity:(CGPoint)velocity 
       targetContentOffset:(inout CGPoint *)targetContentOffset 
{  
    CGFloat rowHeight = tableView.rowHeight; 
    int verticalOffset = ((int)targetContentOffset->y % (int)rowHeight); 
    if (velocity.y < 0) 
    { 
     targetContentOffset->y -= verticalOffset; 
    } 
    else if (velocity.y > 0) 
    { 
     targetContentOffset->y += (rowHeight - verticalOffset); 
    } 
    // No velocity, snap to closest page 
    else 
    { 
     if (verticalOffset < rowHeight/2) 
     { 
      targetContentOffset->y -= verticalOffset; 
     } 
     else 
     { 
      targetContentOffset->y += (rowHeight - verticalOffset); 
     } 
    }  
} 

Notez que la définition plus

self.tableView.decelerationRate = UIScrollViewDecelerationRateFast; 

en viewDidLoad: rend plus proche de la vraie chose, mais pas tout à fait.

J'ai trituré avec réglage des taux de décélération encore plus rapides en utilisant le code shown here mais je ne pouvais pas le faire correctement.

3

Et Swift ...

func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) { 
    if !decelerate { 
     self.scrollViewDidEndDecelerating(scrollView) 
    } 
} 

func scrollViewDidEndDecelerating(scrollView: UIScrollView) { 
    if let indexPathToScrollTo: NSIndexPath = self.tableView.indexPathForRowAtPoint(CGPointMake(self.tableView.contentOffset.x, self.tableView.contentOffset.y+tableView.rowHeight/2)) { 
     self.tableView.scrollToRowAtIndexPath(indexPathToScrollTo, atScrollPosition: UITableViewScrollPosition.Top, animated: true) 
    } 
} 
Questions connexes