2009-06-12 7 views
25

Ho un UITableView cui origine dati e delegato vengono commutati tra un paio di oggetti di origine dati personalizzati quando l'utente tocca un controllo segmentato (si pensi "Inizio pagina Pagato "vs" Top Free "nell'app store dell'app).Forza programmaticamente un UIScrollView per interrompere lo scorrimento, per condividere una vista tabella con più origini dati

Ogni oggetto origine dei dati consente di risparmiare il suo contenuto ultimo rotolo di offset, e lo riporta quando diventa l'origine dati attiva per la vista tavolo facendo:

tableView.contentOffset = CGPointMake(0, savedScrollPosition); 

Questo funziona bene quando l'utente passa l'origine dati quando la tabella è a riposo, ma se l'utente preme il controllo segmentato mentre la tabella è ancora in movimento (cioè in decelerazione), la vista tabella continua a decelerare dal vecchio offset, ignorando in modo efficace il mio incarico contentOffset.

C'è un modo per forzare la visualizzazione tabella a interrompere lo scorrimento/decelerazione quando imposto il contentOffset o un altro modo per rendere funzionante questo tipo di visualizzazione tabella di origine dati commutabile?

risposta

19

Hai provato questi 2 metodi?

Si applicano effettivamente allo "scorrimento" non solo all'offset del contenuto.

[self.tableView scrollToRowAtIndexPath:savedIndexPath atScrollPosition:UITableViewScrollPositionTop animated:NO]; 

O:

[self.tableView scrollRectToVisible:savedFrame animated:NO]; 

Essi dovrebbero effettivamente effettuare lo scorrimento e per estensione l'accelerazione del tavolo, non solo ciò che è visibile sullo schermo.

+2

scrollRectToVisible lo ha fatto, utilizzando la posizione di scorrimento salvata come origine del rect e utilizzando i limiti della vista tabella come altezza. Sei assolutamente corretto che i metodi scroll * controllino l'accelerazione nei modi in cui l'offset del contenuto non lo consente. –

+0

'scrollRectToVisible' ha funzionato anche per me. – zekel

-3

Si potrebbe provare a fare

tableView.scrollEnabled = NO; 
tableView.scrollEnabled = YES; 

Questo potrebbe fermare la pergamena da disabilitarlo, quindi consentire di nuovo. Non l'ho provato in particolare, ma ho fatto cose simili.

+0

Ho provato a impostandola su NO , quindi impostare contentOffset, quindi impostarlo su SÌ. Non ha funzionato, ma potrei anche provare la sequenza NO-YES-offset e vedere se questo fa la differenza. –

0

Si potrebbe attendere che la proprietà di "decelerazione" diventi NO (ad esempio utilizzando KVO) e passare dopo.

+0

Il problema è che ci sarebbe un ritardo piuttosto evidente prima che la posizione di scorrimento possa essere impostata. –

13

Hai provato a utilizzare [view setContentOffset: offset animated: YES]?

+0

Farò un tentativo. Non è esattamente il comportamento che voglio (voglio che la posizione di scorrimento scatti subito), ma potrebbe essere abbastanza buono. –

+8

Questo ha funzionato per me, usando animato: NO. –

+0

animato lo ha fatto – Eugene

0

Uno dei problemi più ovvi consiste nell'avere due viste di tabella distinte che vengono sostituite e ogni origine dati è collegata in modo permanente a una delle viste tabella. Mi è sembrato un po 'uno spreco di memoria, ma forse lo sto pensando troppo.

2

Ho usato l'approccio di Corey. Salvare & ripristinare i rects con la rappresentazione del dizionario. Inoltre, potrebbe non essere ovvio, ma il rettangolo di preservare & ripristino è il limiti del UITableView:

// Save the current tableview bounds 
CGRect contentRect = self.listTableView.bounds; 
if (!!oldScope) [_contentRects setObject:(NSObject *)CGRectCreateDictionaryRepresentation(contentRect) forKey:oldScope]; 

// Restore if possible 
CFDictionaryRef restoredFrameDict = (CFDictionaryRef)[_contentRects objectForKey:newScope]; 
if (!restoredFrameDict) restoredFrameDict = CGRectCreateDictionaryRepresentation(CGRectZero); 
CGRectMakeWithDictionaryRepresentation(restoredFrameDict, &contentRect); 

// Switch over to new datasource 
self.listTableView.dataSource = [self dataSourceForScope:newScope]; 
[self.listTableView reloadData]; 

// Restore content offset for "newScope"; Also stops scrolling 
[self.listTableView scrollRectToVisible:contentRect animated:NO]; 

Si noti l'uso intercambiabile di CFDictionaryRef e NSDictionary *

4

appena trovato questo alla ricerca di un modo per stop al mio UIScrollView - Avevo bisogno di spostare alcune sottoview in giro, ma questa ferita non sembra corretta se l'utente avesse sfogliato lo schermo e stesse ancora rallentando.

In ogni caso - scrollRectToVisible non ha funzionato per me (forse perché non sto usando una vista tabella ??) ma questo ha funzionato perfettamente:

[mainScrollView setContentOffset:CGPointMake(mainScrollView.contentOffset.x, mainScrollView.contentOffset.y) animated:NO]; 

Posso quindi fare la sottoview senza preoccuparmi!

0

Era il mio problema quando avevo un UISwitch come selettore per le tabelle. Ma con il controllo segmentato non ho alcun problema. Forse non hai ricaricato il tavolo? Questo è il mio pezzo di codice di lavoro:

NSIndexPath *exPath = [[subTable indexPathsForVisibleRows] lastObject]; 

isMatchOn = [whatList selectedSegmentIndex] == 0 ? YES : NO; //table source will make the choice looking at this BOOL 

[subTable reloadData]; // here tables actually flip 

if (lastPosition) { 
    [subTable scrollToRowAtIndexPath:lastPosition atScrollPosition:UITableViewScrollPositionBottom animated:NO]; //I scroll to saved index 
    } 
self.lastPosition = exPath; //here I save the current position 
5

questo ha funzionato bene per me:

if (self.tableView.isDecelerating) { 
     NSArray *paths = [self.tableView indexPathsForVisibleRows]; 
     [self.tableView scrollToRowAtIndexPath:[paths objectAtIndex:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; 

    } 
0

È anche possibile fare self.tableView.isScrollEnabled = true/false quando si arriva a un certo tableView.contentOffset.y valore