2014-05-06 15 views
7

Używam widoku UIScrollView jako mojego przewijania stronicowania, pagesScrollView. Wewnątrz tego umieszczam pojedyncze UIScrollViews, które są używane wyłącznie do powiększania. Wewnątrz każdego z nich mam jeden widok, który jest elementem strony, który powinien być powiększany. Wszystko to jest wewnątrz kontrolera UINavigationController z półprzezroczystym navbarem.Granice automatycznie zmieniają się na UIScrollView z wstawkami zawartości

Moje pagesScrollView ma contentInset.top = 64 i bounds.origin.y = -64 (wydaje mi się to dziwne, ale to właśnie system ustawia automatycznie dla mnie), a to działa dobrze. Mój ekran wygląda świetnie!

Jednak po tym, jak przewijać pagesScrollView nawet odrobinę, tak szybko, jak scrollViewWillEndDragging się nazywa, pagesScrollView zaczyna animowany zmiana bounds.origin.y = -64 do bounds.origin.y = 0 co powoduje moje elementy strony mają być zasłonięte przez pasku nawigacyjnym.

Po lewej stronie jest to, jak wygląda po załadowaniu, po prawej jest to, jak wygląda po przeciągnięciu kilku pikseli, a następnie puszczeniu, przesuwa się pod navbar (ponieważ bounds.origin.y idzie do 0).

enter image description here

Problemem jest to, że nie mam żadnego kodu, który jest zmienianie granic i nie mam żadnego kodu w różnych metod przewijania powierzyć to wszystko. Dodałem kilka metod delegatów przewijania i właśnie dodałem NSLog(), aby móc dowiedzieć się, kiedy/gdzie nastąpiła zmiana, ale nie dzieje się to w moim kodzie.

Więc, nie wiem, jaki kod mogę ci pokazać, żeby mi pomóc.

EDYTOWANIE: Zbudowałem nowy projekt od podstaw, aby usunąć wszystkie inne zmienne. Umieszczam nagiego UIViewController w UINavigationController. Umieściłem UIScrollView w moim widoku na cały rozmiar widoku. Poniższy kod jest całym projektem.

Okazuje się, że problem (opisany poniżej) pojawia się tylko raz, gdy PAGING JEST WŁĄCZONY na UIScrollView! Wtf? :)

Oto link do pobrania podstawowego projektu z kilkoma liniami kodu, który demonstruje problem. Po prostu kliknij w przewijanie, a zobaczysz, jak się zmienia, gdy zmieniają się granice. http://inadaydevelopment.com/stackoverflow/WeirdScrollViews.zip

W jaki sposób mogę włączyć stronicowanie w moim przewijanym wierszu bez przerażających granic podczas przewijania i przesuwania wszystkiego pod paskiem nawigacji?

Możliwe jest ustawienie paska nawigacyjnego na nieprzezroczysty i problem jest omijany, ale idealnym rozwiązaniem jest zachowanie standardowego systemu iOS7, aby po powiększeniu widoku zawartości THEN treści mogły znajdować się pod paskiem nawigacji i powinny pokazywać przezroczystość normalnie.

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

    NSArray *colors = @[ 
         [UIColor blueColor], 
         [UIColor orangeColor], 
         [UIColor magentaColor], 
         ]; 

    NSArray *zoomerColors = @[ 
         [UIColor greenColor], 
         [UIColor yellowColor], 
         [UIColor purpleColor], 
         ]; 


    self.scroller.pagingEnabled = YES; 

    [self.scroller setContentSize:CGSizeMake(self.scroller.frame.size.width*colors.count, self.scroller.frame.size.height)]; 

    CGRect subviewFrame = CGRectMake(0, 0, 160, 240); 
    for (int index=0; index < colors.count; index++) { 
     UIColor *color = [colors objectAtIndex:index]; 
     UIColor *zoomerColor = [zoomerColors objectAtIndex:index]; 

     UIView *subview = [[UIView alloc] initWithFrame:subviewFrame]; 
     subview.backgroundColor = color; 

     CGRect zoomerFrame = CGRectMake(index*self.scroller.frame.size.width, 0, self.scroller.frame.size.width, self.scroller.frame.size.height); 

     UIScrollView *zoomer = [[UIScrollView alloc] initWithFrame:zoomerFrame]; 
     [zoomer addSubview:subview]; 
     zoomer.backgroundColor = zoomerColor; 

     [self.scroller addSubview:zoomer]; 

    } 
} 
+0

jeśli używasz granic x i y punkt to 0,0 musisz użyć ramki. –

+0

włóż kod scrollViewWillEndDragging lub ** wprowadź kod poszczególnych UIScrollViews ** – iPatel

+0

@nitinkachhadiya, w ogóle nie zmieniam granic, a granice zaczynają się od -64 ... co mi się nie podobało, ale to właśnie system ustawia się samodzielnie. –

Odpowiedz

11

To błąd systemu iOS. I stworzył następujące podklasy UIScrollView dostać dziennik, co dzieje się y w czasie i która pchała go:

@implementation CSScrollView 

- (void)setContentOffset:(CGPoint)contentOffset 
{ 
    NSLog(@"%0.0f %@", contentOffset.y, [NSThread callStackSymbols]); 
    NSLog(@"[%@]", self.layer.animationKeys); 
    [super setContentOffset:contentOffset]; 
} 

@end 

(i zmienił klasę widok w serii ujęć)

Po zwolnieniu palca , metoda o nazwie UIScrollView _smoothScrollDisplayLink: rozpoczyna animowanie widoku przewijania w jego końcowej pozycji. Zgodnie z drugim logiem nie ma w tym przypadku miejsca, w którym przewijany widok wykorzystuje własne łącze wyświetlania, aby wykonać własne przejście. Wydaje się, że ten niestandardowy kod popełnił błąd podczas animowania z y = whatever do y = 0, nie uwzględniając korekty treści.

Jako proof-of-concept siekać Zmieniłem kod do:

@implementation CSScrollView 

- (void)setContentOffset:(CGPoint)contentOffset 
{ 
    contentOffset.y = -64.0f; 
    [super setContentOffset:contentOffset]; 
} 

@end 

I nic dziwnego, problem odszedł.

Prawdopodobnie nie chcą twardej kodzie -64.0f ale chciałbym stwierdzić:

  • jest to bug iOS;
  • obejść go, odrzucając wartości bezsensowne poprzez podklasę UIScrollView z odpowiednią niestandardową implementacją - setContentOffset:.

rozsądny środki generyczne mogą być do sprawdzenia state z self.panGestureRecognizer - że będziemy pozwalają odróżnić przewija użytkownik jest odpowiedzialny za i inne zwoje bez polegania na każdym nieudokumentowane API lub skomplikowanej przechwytywania zdarzeń delegata. Następnie, jeśli to konieczne, wprowadź poprawną wartość contentOffset.y z bieżącej wartości, zamiast ją kodować.

+0

To jest świetne! Nie mogłem się zorientować, co było nie tak, chociaż podejrzewałem, że to błąd w iOS 8. Działa idealnie z twoim rozwiązaniem, dzięki – Johanneke

0

Moja pagesScrollView ma contentInset.top = 64 i bounds.origin.y = -64 (który wydaje mi się dziwne, ale to, co system automatycznego ustawiania dla mnie), i to działa dobrze . Mój ekran wygląda świetnie!

To z powodu iOS 7 ustawia contentInset.top na 64 we wszystkich przewijanych widokach. Wystarczy dodać następujący wiersz kodu do kontrolera widoku i wszystko będzie działać zgodnie z oczekiwaniami:

-(UIRectEdge)edgesForExtendedLayout { 
return UIRectEdgeNone; 

}

sprawdziłem na przykładzie projektu.

+0

Dzięki za odpowiedź. Niestety, ta odpowiedź pozwala uniknąć problemu, zamiast prawdziwie go rozwiązać. Gdy widok zawartości jest powiększany i przesuwany, zawartość powinna być idealnie pod navbar w tym punkcie i wyświetlać w standardowy sposób iOS7.Mogę sprawić, by navbar był nieprzejrzysty i uniknąć problemów na dobre, ale to nie jest idealny pomysł. To może być bug na iOS. –

15

Wystarczy wyłączyć Ustaw przewijania Zobacz wypustkami

enter image description here

1

Sprawdziłem Ci przykład skorzystać z poniższego kodu w viewController.m złożyć

-(void)viewDidLoad 
{ 
    if ([[UIDevice currentDevice] systemVersion].floatValue>=7.0) { 
     self.edgesForExtendedLayout = UIRectEdgeNone; 
    } 
} 

To działa dobrze ...

+0

Zapobiega wyświetlaniu się błędu, ale to dlatego, że wyłącza funkcję, która jest rdzeń interfejsu użytkownika iOS7. Powinien również działać poprawnie po rozszerzeniu interfejsu użytkownika. –

Powiązane problemy