2013-04-19 14 views
13

Mam dwa widoki przewijania, z których oba powinny przewijać się w pionie. Zewnętrzny widok przewijania (czerwony) zawiera pasek wyszukiwania i wewnętrzny widok przewijania (niebieski). Wewnętrzny widok przewijania ma się przewijać w nieskończoność (zawiera obrazy/elementy i ma niekończącą się implementację przewijania).Zagnieżdżone widoki UIScrollView i routing zdarzeń

Sposób chcę tego kontrolera do pracy jest następujący:

Kiedy przewinąć w dół, zewnętrzna widok przewijania powinna przewijać pierwszy i pasek wyszukiwania powinny zniknąć (przewijanie z obszaru zawartości). Dopiero wtedy wewnętrzny przewijany widok powinien zacząć się przewijać. Podczas przewijania w górę wewnętrzny widok przewijania powinien przewijać się do samego końca. Tylko wtedy widok przewijania zewnętrznego powinien zająć zdarzenia przewijania i ostatecznie przewinąć w górę, aby pasek wyszukiwania był ponownie widoczny.

Jeśli po prostu zagnieżdżę je w IB bez żadnych modyfikacji, wewnętrzny przewijany widok przechwytuje wszystkie zdarzenia przewijania i działa na odwrót.

Proszę wziąć pod uwagę, że używam wewnętrznego przewijania jako uproszczonej metafory tutaj. W mojej aplikacji mam tutaj kontrolę, która ma widok przewijania z zagnieżdżonymi widokami tabel (widok przewijania pozwala mi poziomo, widoki tabel pozwalają mi przewijać w pionie).

enter image description here

+0

czy kiedykolwiek znaleźć rozwiązanie tego, czy obejście? –

Odpowiedz

0

używać tylko jednej Scrollview i ustawić contentInset/contentOffset na pasku wyszukiwania. Coś wzdłuż tej linii:

UIEdgeInsets oldEdgeInset = [[self scrollView] contentInset]; 
    CGRect f = [[self searchBar] frame]; 
    UIEdgeInsets newEdgeInset = UIEdgeInsetsMake(CGRectGetMaxY(f), 0, 0, 0); 
    CGPoint offset = [[self scrollView] contentOffset]; 
    offset.y += oldEdgeInset.top - newEdgeInset.top; 
    [[self scrollView] setContentOffset:offset]; 
    [[self scrollView] setContentInset:newEdgeInset]; 
    [[self searchBar] setFrame:f]; 
+0

Niestety, w moim przypadku jest to nieco bardziej skomplikowane :(Wewnętrzny widok przewijania jest w rzeczywistości pagerem poziomym, który zawiera wiele widoków tabel. Jest to samodzielny widok, którego nie można łatwo rozszerzyć. Poszukuję rozwiązania bardziej w kierunku nakładki superview, która pozwoli mi kierować zdarzenia do odpowiednich widoków przewijania ... – Sebastian

0

nie jestem pewien co do struktury masz i chcą wprowadzić ..

Zrobiłem projekt próba znalezienia here

Ale projekt z pewnością pomoże wam zarządzać różnymi przewijaniami razem ..

Aplikacja może nie być idealna, ale da ci pomysł na rozwiązanie.

Nadzieja to pomaga ..

Cheers

0

Należy dodać wewnętrzną Scrollview na zewnętrznej Scrollview, ale pozycja wewnętrzna Scrollview 'y' powinna być treść off zestaw zewnętrznej Scrollview jak ...

innerScrollView.frame = CGRectMake(10, outerScrollView.contentSize.height, 300, 440); 

Po tym możesz dodać dowolny widok na tym wewnętrznym widoku, możesz ustawić contentOffset etc dla innerScrollView.

Na koniec powinieneś zwiększyć contentSize dla zewnętrznego przewijania.

outerScrollView.contentSize = CGSizeMake(320, innerScrollView.frame.size.height+actualContentSizeOfOuterScroolView); 

Myślę, że to pomaga!

1

Podałem przykład dla jednego przewijania, sametingu trzeba utworzyć onemore przewijania i dodać na podstawie wysokości dynamicznej i wielkości treści, które będzie działać.

//.h plik

@property (nonatomic, strong) UIScrollView *scrlSearch; 

// .m pliku // viewDidLoad

scrlSearch = [[UIScrollView alloc] init]; 

// For first scroll screen height was ((total screen height/100)* 10%) 
// For Second scroll screen height was ((total screen height/100)* 90%) 
scrlSearch.frame = CGRectMake(0, 0, (YourScreenWidth), (YourScreenHeight)); 

// YourVIEW = add any view to scrollbar 
[scrlSearch addSubview:YourVIEW]; 

CGSize contentSize = scrlSearch.frame.size; 
// YourContentHeight = dynamic content or static content height 
contentSize.height = YourContentHeight; 

// set the ContentHeight for scrolling 
[scrlSearch setContentSize:contentSize]; 
// add the scrollview into delegate 
[scrlSearch setDelegate:self]; 
+6

Przykro mi, ale jak to jest nawet odpowiedź? – followben

+0

@ followben Zrobiłem kilka przykładów przy użyciu UIscrollview. co udostępniłem ten kod: – Karthik

2

Jeśli jesteś w stanie ustawić wspólny UIScrollViewDelegate na 2 widoki przewijania i wdrożenia następujących :

- (void) scrollViewDidScroll: (UIScrollView*) scrollView 
{ 
    if (scrollView == self.mainScrollView) 
    { 
    /* Handle instances when the main scroll view is already at the bottom */ 
    if ( scrollView.contentOffset.y 
     == scrollView.contentSize.height - scrollView.bounds.size.height) 
    { 
     /* Stop scrolling the main scroll view and start scrolling the 
     * inner scroll view 
     */ 
     self.innerScrollView.scrollEnabled = YES; 
     self.mainScrollView.scrollEnabled = NO; 
    } 
    else 
    { 
     /* Start scrolling the main scroll view and stop scrolling the 
     * inner scroll view 
     */ 
     self.innerScrollView.scrollEnabled = NO; 
     self.mainScrollView.scrollEnabled = YES; 
    } 
    } 
    else if (scrollView == self.innerScrollView) 
    { 
    /* Handle instances when the inner scroll view is already at the top */ 
    if (self.innerScrollView.contentOffset.y == 0) 
    { 
     /* Stop scrolling the inner scroll view and start scrolling the 
     * main scroll view 
     */ 
     self.innerScrollView.scrollEnabled = NO; 
     self.mainScrollView.scrollEnabled = YES; 
    } 
    else 
    { 
     /* Start scrolling the inner scroll view and stop scrolling the 
     * main scroll view 
     */ 
     self.innerScrollView.scrollEnabled = YES; 
     self.mainScrollView.scrollEnabled = NO; 
    } 
    } 
} 

Należy pamiętać, że nie testowałem tego, ale logika może wyglądać mniej więcej tak (możesz włączyć przewijanie włączone lub wyłączyć interakcję użytkownika lub coś takiego). Najprawdopodobniej to nie będzie wystarczające rozwiązanie, jak chcesz, ale jestem pewien, że wspólny UIScrollViewDelegate jest rozwiązaniem twojego problemu.

+0

Próbowałem tego i to działa "trochę" Problem polega na tym, że gest przewijania/przeciągania nie jest przenoszony z jednego widoku przewijania do drugiego, jeśli robisz to zgodnie z propozycją. przesuń ponownie do przewijania drugiego przewijania – Sebastian

+0

Możesz użyć panGestureRecognizer scrollView do pobrania prędkości, z której użytkownik przesuwa, obliczyć zarówno czas trwania animacji i deltę przesunięcia treści i fałszowanie panoramy na mainScrollView lub innerScrollView, gdy druga osiągnie górną/dolną krawędź. –

+1

@Sebastian co zrobiłeś, aby rozwiązać ten problem? – SAHM

0

Utwórz narzędzie do rozpoznawania gestów machnięcia do swojego najwyższego widoku (przede wszystkim widoków przewijania, w widoku kontrolera widoku) i spraw, aby rozpoznał on UISwipeGestureRecognizerDirectionUp.

Następnie należy powiadomić kontroler, gdy przewijany jest zewnętrzny widok przewijania. Po przewinięciu w dół, dodaj urządzenie do rozpoznawania gestów. Kiedy ponownie uderzy w górę (outerScrollView.contentOffset == (0,0)), usuń narzędzie do rozpoznawania gestów.

Gest powinna „jeść” wszystkie wydarzenia przesuwając jednocześnie jest obecny, dzięki swoim wewnętrznym widoki przewijania nie otrzyma dotykowy zdarzenia i dlatego nie będzie przewijać