2011-10-17 23 views
10

C'è un modo per far scorrere UITableViews dalla cella alla cella? Cioè, la parte superiore della Vista tabella è sempre la parte superiore di UITableViewCell.Forza UITableView per scorrere fino a Celle di celle

Ho provato il flag di paginazione, ma sembra scorrere per intero "pagine". Voglio solo il passaggio da una cella all'altra.

Grazie

risposta

20

UTTableView è una sottoclasse di UIScrollView, in modo da poter utilizzare scrollViewDidScroll metodo per riorganizzare la vostra posizione di scorrimento TableView dopo scorrimento.

È possibile utilizzare tableView.contentOffset per ottenere la posizione di scorrimento corrente. E dividendolo in un numero significativo puoi ottenere quale cella è in cima.

int cellIndex = tableView.contentOffset/cellHegiht; 

Oppure si può ottenere cellule attualmente visibile sul centro (in alto, in basso) in questo modo:

NSArray *indexPathsForVisibleRows = [tableView indexPathsForVisibleRows]; 
NSIndexPath *selectedIndexPath = [indexPathsForVisibleRows objectAtIndex:(indexPathsForVisibleRows.count/2)]; //this gets center cell 

Dopo aver calcolato quale cella dovrebbe essere cliccato per il bordo in alto (o in basso) è possibile correggere la deriva dal bordo cellulare chiamando:

[tableView scrollToRowAtIndexPath:selectedIndexPath atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

È possibile utilizzare UIScrollViewDelegate metodi per attivare snapping. È possibile attivare sia quando l'animazione a scorrimento è completata o mentre l'animazione continua ancora. Ciò genererà diverse interazioni con gli utenti e non si può dire che uno sia migliore di un altro.

Ma proprio l'implementazione del metodo e nient'altro che segue sembra andare a essere il mio preferito:

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView 
        withVelocity:(CGPoint)velocity 
       targetContentOffset:(inout CGPoint *)targetContentOffset { 
    int cellHeight = 41; 
    *targetContentOffset = CGPointMake(targetContentOffset->x, 
             targetContentOffset->y - (((int)targetContentOffset->y) % cellHeight)); 
} 

Questo metodo viene chiamato quando l'utente tocca su TableView per notificare l'applicazione. targetContentOffset è una variabile inout in modo da poter effettivamente impostare la posizione di scorrimento finale mentre l'animazione continua. Usando il diritto cellHeight, il tuo TableView scatterà sempre alle celle.

+2

Grazie per aver mostrato come utilizzare la variabile 'inout'. Funzionalità molto bella! – Besi

+0

+1 Ti ringrazio anche indicando la variabile "inout". – jpswain

+0

Con i tuoi calcoli, non puoi mai scorrere fino all'ultima riga del tavolo ... non è un problema risolverlo. - sicuramente la migliore soluzione per questo. – scottbates22

0

È sufficiente chiamare scrollToRowAtIndexPath:atScrollPosition:animated: e passarlo nel percorso dell'indice corretto per la cella desiderata.

1

Anche se completamente corretto, non ho trovato la risposta di @randle molto utile. Ho letto la documentazione degli sviluppatori ed ero ancora più confuso. Come mai ho finalmente scoperto quanto fosse semplice la risposta, ma a volte abbiamo bisogno di un po 'più di aiuto che "chiama questo metodo". Vedere sotto il commento // scorrere fino a file! qui:

- (BOOL)textFieldShouldReturn:(UITextField *)textField 
{ 
    if (textField == self.firstInput) { 
     [self.secondInput becomeFirstResponder]; 

     // scroll to row! 
     [self.tableView scrollToRowAtIndexPath: // use the method 
      [NSIndexPath indexPathForRow:1  // get 2nd row (nth row...) 
           inSection:0] // in 1st section (...) 
         // set position: you can use bottom, middle or top. 
         atScrollPosition:UITableViewScrollPositionBottom 
           animated:YES]; // YES or NO. 

    } else if (textField == self.secondInput) { 
     [textField resignFirstResponder]; 
    } 
    return YES; 
} 

Ora, questo è per una tabella di celle staticheView. Conosco la quantità di file, so quale riga sto andando. Questo potrebbe essere ampliato per migliorare il codice e l'accesso alle variabili a livello di codice, ma mostra COME questo codice funziona in pratica a un livello basso.

Spero che questo aggiunga un livello di utilità a chiunque altro cerchi nel forum.

ho fatto una scrittura completa up del metodo qui: http://iosanswers.blogspot.com/2012/02/table-view-forms-scroll-to-selected.html

3

Se si dispone di sezioni, ho trovato questo l'approccio più affidabile:

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate(BOOL)decelerate { 
    if (decelerate == NO) { 
     [self autoAdjustScrollToTop]; 
    } 
} 
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    [self autoAdjustScrollToTop]; 
} 
- (void)autoAdjustScrollToTop { 
    // compare the top two visible rows to the current content offset 
    // and auto scroll so that the best row is snapped to top 
    NSArray *visibleRows = [self.tableView indexPathsForVisibleRows]; 
    NSIndexPath *firstPath = visibleRows[0]; 
    NSIndexPath *secondPath = visibleRows[1]; 
    CGRect firstRowRect = [self.tableView rectForRowAtIndexPath:firstPath]; 
    [self.tableView scrollToRowAtIndexPath:(firstRowRect.origin.y > self.tableView.contentOffset.y ? firstPath : secondPath) atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
} 
1

Questo approccio gestisce una vista tabella con diverse altezze di riga . Presume che la vista tabella abbia una singola sezione.

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView 
        withVelocity:(CGPoint)velocity 
       targetContentOffset:(inout CGPoint *)targetContentOffset { 

    // Find the row where the animation will currently end. 
    NSInteger targetRow = [[self.tableView indexPathForRowAtPoint:*targetContentOffset] row]; 

    // Tell the animation to end at the top of that row. 
    *targetContentOffset = [self offsetForTopOfRow:targetRow]; 
} 

L'offset viene calcolato da questo metodo di supporto, che somma l'altezza di tutte le righe sopra la riga di destinazione.

- (CGPoint)offsetForTopOfRow:(NSInteger)row { 

    CGPoint offset = CGPointZero; 

    for (int i = 0; i < row; i++) { 
     NSIndexPath *indexPath = [NSIndexPath indexPathForRow:i inSection:0]; 
     CGFloat height = [self.tableView.delegate tableView:self.tableView heightForRowAtIndexPath:indexPath]; 
     offset.y += height; 
    } 

    return offset; 
} 
0

Questo funziona bene se si dispone di sezioni e file con altezze statiche.

func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { 
    // Adjust target offset so that cells are snapped to top 
    let cellHeight: CGFloat = 44 
    let headerHeight: CGFloat = 30 
    let section = (indexPathsForVisibleRows?.first?.section ?? 0) + 1 
    targetContentOffset.memory.y -= (targetContentOffset.memory.y % cellHeight) - (CGFloat(sectionIndex) * headerHeight) 
} 
Problemi correlati