2010-10-15 17 views
37

To jest bardzo dziwne i zastanawiam się, czy ktoś ma jakieś myśli?Problem z podglądem uiscrollview setcontentoffset animowany, nie przewijający po animacji: tak ustawiony

Próbuję przewinąć UIScrollView w odpowiedzi na naciśnięcie przycisku na iPadzie.

Jeśli zrobić:

CGPoint currentOff = scrollView.contentOffset; 
currentOff.x+=240; 
[scrollView setContentOffset:currentOff animated: NO]; 

Zwój widok skacze do żądanej pozycji zgodnie z oczekiwaniami, ale chcę go przewinąć. Jednak gdy to zrobię:

CGPoint currentOff = scrollView.contentOffset; 
currentOff.x+=240; 
[scrollView setContentOffset:currentOff animated: YES]; 

To nic nie da! Mam inny widok przewijania, który działa poprawnie i odpowiada zgodnie z oczekiwaniami na setContentOffset:YES, więc jestem dość zaintrygowany. Wszelkie pomysły na to, dlaczego przewijanie nie może się wydarzyć, są mile widziane!

Ponadto, - (void)scrollViewDidScroll:(UIScrollView *)sender nie otrzymuje niczego w ogóle, gdy jest używane animated:YES, ale jest wywoływane, gdy użyto animated:NO!

+2

hm, widzę coś bardzo podobnego. zarówno setContentOffset, jak i scrollRectToVisible działają zgodnie z oczekiwaniami z animated = false, ale nie robią nic z animated = true. również ciekawy, jeśli przeciągnę nieco scrollView palcem, a następnie spróbuję ponownie przycisku, to działa. wydrukowałem zawartość contentSize scrollView i wygląda ona poprawnie. –

+0

Zabawne, po prostu miałem ten sam problem, ale odwróciłem. Działa tylko wtedy, gdy je animuję. –

+1

Hi. sprawdź moją odpowiedź na http://stackoverflow.com/a/27088865/1510171 – tomeron11

Odpowiedz

72

miałem to się stało i skończyło się zbyt robi tego obejścia:

[UIView animateWithDuration:.25 animations:^{ 
    self.scrollView.contentOffset = ...; 
}]; 
+2

Miałem ten sam problem, to obejście pracowało dla mnie też! dzięki! –

+0

możesz wyjaśnić, co może być powodem (dla setContentOffset: animowany: nie działa i działa w ten sposób) – Tatvamasi

+2

Nie jestem pewien, myślę, że to błąd, że wersja animowana nie działa. –

0

można spróbować:

[scrollView setContentOffset:CGPointMake(240, 0) animated:YES]; 
2

Trudno powiedzieć z tego kawałka kodu dałeś. I faktycznie, jeśli mówisz, że masz projekt, w którym wszystko działa w tych samych warunkach, to oczywiście warunki nie są takie same :) Nie mogłem odtworzyć problemu, ale oto kilka założeń dla 2 przypadki:

  1. Utworzenie UIScrollView za pomocą stalówki.

    • Po prostu nie zapomnij stworzyć IBOutlet i powiązać go z elementem scrollView w stalówce. W prostej aplikacji opartej na widoku zaraz po tym uzyskałem pracę scrollView tak, jak chciałeś w animacji: zarówno TAK, jak i NIE. Ale aby praca

    -(void)scrollViewDidScroll:(UIScrollView *)sender; należy ustawić delegata:

yourScrollView.delegate = self;

gdzie 'ja' jest klasa, gdzie masz swoją funkcję scrollViewDidScroll; btw ta klasa musi być zgodna z protokołem "UIScrollViewDelegate".

2. Tworzenie ręcznie obiektu UIScrollView.

  • tutaj pomysł jest w zasadzie taki sam, więc ja po prostu zapewnić pewien prosty kod:

    -(void) creatingScrollView { 
        UIScrollView *newScroll = [[UIScrollView alloc] initWithFrame:CGRectMake(20, 5, 280, 44)]; 
        newScroll.pagingEnabled = YES; 
        newScroll.showsVerticalScrollIndicator = NO; 
        newScroll.showsHorizontalScrollIndicator = NO; 
    
        // ... some subviews being added to our scroll view 
    
        newScroll.delegate = self; 
        [self.view addSubview:newScroll]; 
        [newScroll release]; 
    } 
    

Działa to dla mnie. Mam nadzieję, że to jest pomocne.

7

Mówiąc z własnego doświadczenia, ten problem występuje, gdy setContentOffset: uzyskiwanie nazywany wiele razy zanim animacja miał okazję do uruchomienia.

Nie wytropił całkowicie problemu, ale wierzę, że problem wykracza coś takiego:

setContentOffset: animowane pobiera nazywane która ustawia nową wartość offsetu. setContentOffset: następnie zostaje wywołany z tymi samymi parametrami, co powoduje anulowanie animacji. Zauważa również, że nowe parametry są takie same jak stare parametry, więc nie trzeba nic robić, nawet jeśli animacja jeszcze nie działa.

Rozwiązanie powyżej w jakiś sposób przerywa ten cykl, ale być może mniej kludgy rozwiązaniem jest umieszczenie punktów przerwania w kodzie i wyeliminowanie wielu połączeń.

+0

To wyjaśnienie pomogło mi w podobnym zagadnieniu. Dzięki! – chadbag

+1

Moja poprawka polegała na usunięciu połączenia z 'setNeedsLayout' po' setContentOffset: animated'. –

+0

um, co to jest "powyższe rozwiązanie", lol? rozwiązanie z makaronem? – Harris

0

Mam taki sam problem, że ScrollView nie przewija. I wyłączyłem "Użyj automatycznego układu" w widoku, a następnie działa ScrollView.

0

miałem ten sam problem, w moim przypadku był również chwytny:

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {...} 

Metoda ta nazywana jest natychmiast po: (To nie czekać do końca animacji):

[scrollView setContentOffset:currentOff animated: YES]; 

Co oznacza, że ​​jeśli masz jakąś logikę, która "czeka" na koniec animacji i przechwycisz scrollViewDidEndScrollingAnimation, wynik będzie niezdefiniowany, IE: przedwczesne zakończenie animacji.

EDIT: akceptowane rozwiązanie/obejście:

[UIView animateWithDuration:.25 animations:^{ 
    self.scrollView.contentOffset = ...; 
}]; 

także "dzieła" w moim scenariuszu ponieważ ustawienie contentOffset bezpośrednio nie powoływać scrollViewDidEndScrollingAnimation

1

rozwiązanie dla Xamarin.iOS

InvokeOnMainThread(() => 
{ 
    scrollView.SetContentOffset(new PointF((page * UIScreen.MainScreen.Bounds.Width), 0), true); 
}); 

Można to również rozwiązać, korzystając z UIView.Animate

UIView.Animate(
    duration: .25, 
    animation:() => 
    { 
     scrollView.SetContentOffset(new PointF((value * UIScreen.MainScreen.Bounds.Width), 0), true); 
    } 
); 
+0

Czy podczas animacji niestandardowej ('UIView.Animate') nie powinno być' animowane' jest * fałsz *? – testing

0
func scrollViewDidScroll(scrollView: UIScrollView) { 

    dispatch_async(dispatch_get_main_queue(),{ 

     UIView.animateWithDuration(0.10, animations: {() -> Void in 

      let loginScrollViewCurrentPosition:CGPoint = CGPointMake(self.loginScrollView.contentOffset.x, self.loginScrollView.contentOffset.y) as CGPoint 
      self.loginScrollView.setContentOffset(loginScrollViewCurrentPosition, animated: true) 

      }) 
    }) 

}