2010-05-28 17 views
9

Una vista con un tavolo viene spinta sullo schermo e voglio che scorra fino a una determinata riga nella tabella prima che lo schermo venga effettivamente visualizzato. Io uso questo codice all'interno del viewcontroller finale.Scorrere immediatamente nella riga della tabella prima di visualizzare mostra

NSIndexPath *scrollToPath = [NSIndexPath indexPathForRow:5 inSection:0]; 
[theTable scrollToRowAtIndexPath:scrollToPath atScrollPosition:UITableViewScrollPositionTop animated:NO]; 

Quando messo in metodo viewDidAppear, poi lampeggiare brevemente dalla posizione intial del tavolo (in alto) alla riga voglio. Non voglio che mostri la posizione iniziale. Se lo metto in viewDidLoad o viewWillAppear, si blocca con una NSRangeException, presumibilmente perché la tabella non è ancora impostata.

Come faccio a farlo scorrere senza mostrare la posizione iniziale?

+1

[Questo] (http://stackoverflow.com/questions/2289114/make-uitableview-selection-before-view-appears/2289812#2289812) e [questo] (http: // StackOverflow. it/questions/2156614/how-to-start-uitableview-on-the-last-cell) potrebbe aiutare. – DyingCactus

risposta

13

Grazie a Shaggy e Morire Cactus per avermi nella giusta direzione. La risposta è quella di caricare la tabella e scorrere in viewWillAppear:

-(void)viewWillAppear:(BOOL)animated 
{ 
    [theTable reloadData]; 
    NSIndexPath *scrollToPath = [NSIndexPath indexPathForRow:5 inSection:0]; 
    [theTable scrollToRowAtIndexPath:scrollToPath atScrollPosition:UITableViewScrollPositionTop animated:NO]; 
} 
+1

Assicurati di contrassegnare la tua risposta come accettata in modo che altri che leggono questa domanda possano vederla a colpo d'occhio :) – BoltClock

+0

Questo è ottimo per ciò di cui avevo bisogno. L'unica cosa che ho fatto è che ho usato UITableViewScrollPositionNone invece di ScrollPositionTop in modo che gli utenti potessero vedere il più possibile la tabella sopra la riga selezionata. – RanLearns

+1

Questo non funziona per me perché nelle versioni più recenti di iOS (5 e 6) non vedo i frame impostati dal sistema operativo fino a dopo viewWillAppear. viewWillLayoutSubviews/viewDidLayoutSubviews non vengono richiamati fino a dopo viewDidAppear. – Logachu

2

Se metterà in viewDidLoad o viewWillAppear allora si blocca con un NSRangeException, presumibilmente perché la tabella non è ancora configurato.

Perché il tavolo non è stato ancora impostato? In quale metodo lo stai configurando?

+0

bene viene creato in cellforrowatindexpath – cannyboy

+1

Puoi caricare la tabella in viewWillAppear –

1

Ho appena finito di lottare con questo. Il mio stava aggiungendo una barra di ricerca in cima alla lista, inizialmente nascosta sotto la parte superiore ... ad alcune delle applicazioni principali. In realtà stavo per fare questa stessa domanda!

ho paura di offrire questo in su, come sembra coloro che offrono le cose ottenere pestate giù .. ma ... sono rimasto sorpreso che non c'era una soluzione facile ... così ho finito per fare questo:

Io uso ABTableViewCell (puoi google) per le celle disegnate su misura (bello e veloce!), E quando mi chiamano per disegnare la seconda riga (puoi farlo nelle celle disegnate in modo personalizzato senza ABTableViewCell), l'ho impostato lì , con un unico semaforo del fuoco:

if (self.mOnlyOnce == NO && theRow > 1) { 
    self.mOnlyOnce = YES; 
    [self.mParentTable scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:1] atScrollPosition:UITableViewScrollPositionTop animated:NO]; 
} 

(scegliere la vostra riga/sezione corretta, come più vi si addice ... se fossero nella stessa sezione, si sarebbe probabilmente essere impostando fila per qualcosa diverso da 0)

Se odiate la mia soluzione (come non posso ancora commentare), per favore fatemi il favore di lasciarlo a zero & lasciando che una soluzione migliore arrivi in ​​cima.

Oh, inoltre, c'è una voce che nasconde la ricerca in alto ... ma il mio era già stato fatto come una cella personalizzata ... ecco che link.

godono

-1

in iOS 8 e sopra [self.tableView reloadData] in viewWillAppear prima scrollToRowAtIndexPath non funziona, quello che dovete fare reload in viewDidAppear come indicato di seguito:

- (void)viewDidAppear:(BOOL)animated 
{ 
    [super viewDidAppear:YES]; 

    [self.tableView reloadData]; 

    [self.tableView scrollToRowAtIndexPath:[[NSIndexPath indexPathForRow:18 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

} 

Nota: è necessario utilizzare UITableViewScrollPositionTop, altrimenti lo scorrimento non sarà come previsto e potrebbe scorrere fino in fondo e persino alle aree vuote dopo l'ultima riga se si specifica scrollToRow come ultima riga.

Penso che in iOS 8 e sopra la prima volta che viene caricato il TableView non carichi tutti i dati utilizzati per costruire la tabella, questo è il motivo per cui devi usare [tableView reload] che a mio avviso è un po 'strano.

2

Chiamare scrollToRowAtIndexPath: in viewWillAppear: non funziona per me perché tableView non è stato ancora caricato. Ma potrei risolvere questo problema chiamando lo scrollToRowAtIndexPath: dopo qualche ritardo.

- (void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 

    [self performSelector:@selector(scrollToCell) withObject:nil afterDelay:0.1]; 
} 

- (void) scrollToCell 
{ 
    [_tableView reloadData]; 
    NSIndexPath *scrollToPath = [NSIndexPath indexPathForRow:5 inSection:0]; 
    [_tableView scrollToRowAtIndexPath:scrollToPath atScrollPosition:UITableViewScrollPositionTop animated:NO]; 
} 

Spero che possa aiutare qualcuno.

+2

Questa risposta funziona meglio ma puoi utilizzare anche dispatch_after. – harshalb

+0

Ho provato molte cose su iOS 8 e solo questo funziona. Ma funziona anche con 'dispatch_async' sul thread principale. –

+0

il ritardo di 0 funziona anche bene, e ha un aspetto migliore di 100ms dove lo vedrai ancora saltare di 100ms dopo aver spinto il tavolo –

1

È possibile utilizzare GCD per inviare lo scorrimento alla successiva iterazione del ciclo di esecuzione principale in viewDidLoad per ottenere questo comportamento. Lo scroll verrà eseguito prima che la vista tabella venga mostrata sullo schermo, quindi non lampeggerà.

- (void)viewDidLoad { 
    dispatch_async (dispatch_get_main_queue(), ^{ 
     NSIndexPath *indexPath = YOUR_DESIRED_INDEXPATH; 
     [self.tableView scrollToRowAtIndexPath:indexPath atScrollPosition:UITableViewScrollPositionTop animated:NO]; 
    }]; 
} 
4

ho avuto lo stesso identico problema, dopo aver provato tutto, questo ha funzionato, la chiave è se si sta utilizzando layout automatico, è necessario scrivere codice scrollToBottom in viewDidLayoutSubviews

inizializzare scrollToBottom true e poi fare questo

- (void)viewDidLayoutSubviews { 
    [super viewDidLayoutSubviews]; 
    // Scroll table view to the last row 
    [self scrollToBottom]; 
} 

-(void)scrollToBottom { 
    if (shouldScrollToLastRow) 
    { 
     CGPoint bottomOffset = CGPointMake(0, self.tableView.contentSize.height - self.tableView.bounds.size.height); 
     [self.tableView setContentOffset:bottomOffset animated:NO]; 
    } } 

facendo questo farà sì che sei quasi in fondo sei tableView ma potrebbe non essere in fondo come la sua impossibilità di conoscere l'esatto fondo di offset quando sei in cima alla tableView , quindi dopo possiamo implementare scro llViewDidScroll

-(void)scrollViewDidScroll: (UIScrollView*)scrollView 
{ 
    float scrollViewHeight = scrollView.frame.size.height; 
    float scrollContentSizeHeight = scrollView.contentSize.height; 
    float scrollOffset = scrollView.contentOffset.y; 

    // if you're not at bottom then scroll to bottom 
    if (!(scrollOffset + scrollViewHeight == scrollContentSizeHeight)) 
    { 
     [self scrollToBottom]; 
    } else { 
    // bottom reached now stop scrolling 
     shouldScrollToLastRow = false; 
    } 
} 
Problemi correlati