2009-06-12 12 views
25

Mam UITableView, którego źródło danych i delegat są przełączane między kilkoma niestandardowymi obiektami źródła danych, gdy użytkownik dotknie kontrolki podzielonej na segmenty (myślę, że "Top Płatne "vs" Najlepsze bezpłatne "w aplikacji sklepu z aplikacjami).Programowo wymuszaj zatrzymanie przewijania przez narzędzie UIScrollView, aby udostępnić widok tabeli z wieloma źródłami danych.

Każdy obiekt źródła danych zapisuje jego treść ostatni przewijania offsetu i przywraca go, gdy staje się aktywnym źródłem danych dla widoku tabeli wykonując:

tableView.contentOffset = CGPointMake(0, savedScrollPosition); 

Działa to dobrze, gdy przełącza użytkownik źródła danych, gdy tabela jest w spoczynku, ale jeśli użytkownik uderzy w segmentowany element sterujący, gdy tabela nadal się porusza (tj. spowalnia), widok tabeli nadal zwalnia z poprzedniego offsetu, skutecznie zastępując moje przydziały contentOffset.

Czy istnieje sposób zmuszenia widoku tabeli do zatrzymania przewijania/zwalniania podczas ustawiania zestawu contentOffset lub innego sposobu wyświetlania tego typu widoku tabeli przełączalnych źródeł danych?

Odpowiedz

19

Czy próbowałeś tych 2 metod?

W rzeczywistości dotyczą one "przewijania", a nie tylko przesunięcia zawartości.

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

OR:

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

Powinny one faktycznie wpływać na przewijanie i co za tym idzie przyspieszenie tabeli, a nie tylko to, co jest widoczne na ekranie.

+2

Funkcja scrollRectToVisible zrobiła to, wykorzystując zapisaną pozycję przewijania jako początek prostokąta i używając granic widoku tabeli jako wysokości. Masz absolutną rację, że metody przewijania * sterują przyspieszeniem w sposób, w jaki ustawienie kompensacji treści nie działa. –

+0

'scrollRectToVisible' pracował również dla mnie. – zekel

-3

Można spróbować zrobić

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

To może przestać zwój wyłączając go, a następnie pozwolić jej ponownie. Nie próbowałem tego specjalnie, ale robiłem podobne rzeczy.

+0

tableView.contentOffset.y Próbowałem ustawienie go na NO , następnie ustaw właściwość contentOffset, a następnie ustaw ją ponownie na YES. To nie zadziałało, ale równie dobrze mógłbym spróbować przesunięcia NO-YES-offset i sprawdzić, czy to robi różnicę. –

0

Możesz poczekać, aż właściwość "spowolnienie" stanie się NIE (np. Za pomocą KVO) i przełączać po tym.

+0

Problem polega na tym, że może wystąpić zauważalne opóźnienie, zanim można będzie ustawić pozycję przewijania. –

13

Czy próbowałeś już korzystać z [view setContentOffset: offset animated: YES]?

+0

Dam mu szansę. Nie jest to dokładnie to, czego pragnę (chcę, aby pozycja przewijania natychmiast się odskoczyła), ale może być wystarczająco dobra. –

+8

To zadziałało dla mnie, używając animacji: NIE. –

+0

animowane czy to – Eugene

0

Jednym z oczywistych zadań jest posiadanie dwóch oddzielnych widoków tabel, które zostają zamienione, a każde źródło danych jest trwale podłączone do jednego z widoków tabel. To wydawało się trochę marnowaniem pamięci, ale być może nad tym myślę.

2

Użyłem podejścia Coreya. Oszczędzam & przywracam rects z reprezentacją słownika. Ponadto, nie może być oczywiste, ale rect zachować & przywrócić jest granice z 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]; 

zanotować wymienne stosowanie CFDictionaryRef i NSDictionary *

4

Wystarczy znaleźć to szuka sposobu na Zatrzymaj mój UIScrollView - musiałem przenieść niektóre subviews dookoła, ale nie wyglądało to dobrze, gdyby użytkownik włączył ekran i nadal zwalniało.

W każdym razie - scrollRectToVisible nie działa dla mnie (może dlatego, że nie używam widoku tabeli?), ale zadziałało idealnie:

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

Mogę wtedy robić zdjęcia z podglądu bez obawy!

0

To był mój problem, gdy miałem przełącznik UISwitch jako selektor dla stołów. Ale z segmentowaną kontrolą nie mam żadnego problemu. Może nie przeładowałeś stołu? To jest mój kawałek kodu pracy:

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

Ten pracował dobrze dla mnie:

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

    } 
0

Można również zrobić self.tableView.isScrollEnabled = true/false kiedy dojdziesz do pewnej wartości