2012-02-03 8 views
21

W tej chwili mam widok spoza widoku UIScrollView. Z wielu powodów nie może być po prostu wewnątrz przewijania. Więc teraz, co robię, ponieważ UIScrollView jest skalowany/przesuwany, aktualizuję mój drugi widok pomocniczy. Jedyny problem, na który się natknę, to to, że wartość zoomScale nie jest dostosowywana, podczas gdy widok wraca do minimalnej lub maksymalnej skali. Wszelkie sugestie, jak uzyskać tę wartość podczas animacji z powrotem?Właściwość zoomScale programu UIScrollView nie jest aktualizowana podczas podskakiwania pod kątem powiększenia

Przykładowy kod:

self.scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, appSize.width, appSize.height)]; 
self.scrollView.contentSize = CGSizeMake(appSize.width * 2, appSize.height * 2); 

self.scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite; 
self.scrollView.delegate = self; 
self.scrollView.bounces = YES; 
self.scrollView.bouncesZoom = YES; 
self.scrollView.alwaysBounceHorizontal = YES; 
self.scrollView.alwaysBounceVertical = YES; 
self.scrollView.showsHorizontalScrollIndicator = YES; 
self.scrollView.showsVerticalScrollIndicator = YES; 

self.scrollViewZoomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 
                    appSize.width * 2, 
                    appSize.height * 2)]; 
[[self scrollView] addSubview:self.scrollViewZoomView]; 

float minZoomScale = 2.0f; 

self.scrollView.minimumZoomScale = minZoomScale; 
self.scrollView.maximumZoomScale = 1.0f; 
self.scrollView.zoomScale = self.scrollView.minimumZoomScale; 

a potem na siebie

-(void) scrollViewDidZoom:(UIScrollView *)scrollView { 
    float scale = [scrollView zoomScale]; 
    [self updateAuxViewScale:scale]; 
} 
+0

nie można po prostu animować pomocniczego celu jej min/max skali kiedy 'scrollViewDidEndZooming: withView: atScale:' nazywa? Myślę, że animacja "odbija się" ma ustalony czas trwania. – omz

Odpowiedz

4

Dzięki this answer staje się jasne, że można użyć presentationLayer, aby uzyskać prawidłowe wartości. Utworzono UIScrollViewcategory, aby dodać specjalne moduły pobierające dla zoomScale, contentOffset i contentSize, które zwracają poprawne wartości, nawet jeśli animacja dotyczy obiektu UIScrollView.

można znaleźć repo tutaj: https://github.com/bddckr/BDDRScrollViewExtensions

+1

Uratowałeś mi mnóstwo czasu. Świetna robota. – fionbio

+0

Używam tego podejścia, ale często stwierdzam, że ostateczne wartości warstwy prezentacji nie pasują do tego, co powinny. To tak, jakby przestało być krótkie. – Benjohn

2

Należy użyć innej metody UIScrollViewDelegate.

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale { 
    // Your code here 
    float scale = [scrollView zoomScale]; 
    [self updateAuxViewScale:scale]; 
} 

Zgodnie z docs: https://developer.apple.com/library/ios/#documentation/uikit/reference/uiscrollviewdelegate_protocol/Reference/UIScrollViewDelegate.html

"Widok przewijania nazywa tę metodę także po wszelkich«bounce»animacji".

+5

Całkowicie zapomniałem o tym poście do teraz. Zajmowałem się tym, jak jest, ale chcę to naprawić przed uruchomieniem. Problem polega na tym, że mogę określić skalę, gdy użytkownik aktywnie powiększa, a także kiedy animacje "odbicia" są zakończone, ale jest to właściwa animacja, którą chcę przekazać dalej. Podczas animacji z odbiciem przybliżonym chciałbym wiedzieć, czym jest OBECNY zoom - czyli poziom powiększenia w określonym przedziale animacji. –

+1

Naprawdę chcę to rozwiązać. Patrzę teraz na KVO, aby obejrzeć prezentację Layer widoku, ale też nie dostaję żadnego callbacka. Chciałbym rozwiązać ten problem. – bobmoff

-2

Według mojej wiedzy, jeśli chcesz poznać aktualny poziom powiększenia, należy użyć następującej metody delegata UIScrollView

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(float)scale 
{ 

     NSLog(@"Zoomscale %f",scale); 

} 

nadzieję, że będzie przydatna.

Ciesz się programowaniem!

+0

To rozwiązanie w rzeczywistości nie rozwiązuje mojego problemu. Mój problem polega na tym, że chcę się dowiedzieć, jaka jest aktualna skala zoomu w części animacji z funkcją Odbicie-zoom. Próbowałem każdej metody delegatów, a także KVO bezskutecznie. –

+0

ohh .. Dlaczego tak. Zrobiłem to samo w mojej aplikacji, używając tylko tej metody delegowania .. !! –

+0

Ponieważ mój widok jest za niewidoczny UIScrollView. Używam UIScrollView dla jego fizyki - więc przekazuję współczynnik skali z UIScrollView do widoku pomocniczego. Dlatego muszę wiedzieć, czym jest skala zoomu, nawet gdy odbija się od animacji. –

1

Okej, myślę, że mogłem znaleźć coś, co ci pomoże. W tym wątku pokrewnym In iOS 4.0, why does UIScrollView zoomToRect:animated: not trigger the scrollViewDidScroll or scrollViewDidZoom delegates while animating? znajdują się dwie odpowiedzi, które mogą ci się przydać.

  1. https://stackoverflow.com/a/15512253/1011213
  2. https://stackoverflow.com/a/7553969/1011213

Osobiście uważam, że dałbym pierwsze rozwiązanie strzał. Mam nadzieję, że rozumiem pytanie i jest to pomocne. Jeśli nie ... przepraszam i najśmieszniejsze kodowanie!

5

Odbicie zoomu jest animacją, więc właściwość zoomScale jest natychmiast wartością docelową animacji, nawet jeśli animacja jest nadal uruchomiona. Jeśli chcesz zastosować tę samą skalę powiększenia że widok przewijania ma do innego widoku, tutaj jest sposób, aby je odzyskać:

  1. W -scrollViewDidScroll: sprawdzić czy widok zawartość ma animacji.
  2. Jeśli nie ma animacji, ustaw nową skalę zoomu.
  3. Jeśli istnieją animacje, uzyskaj czas trwania jednego z nich (wszystkie powinny być równe) i animuj swój widok z tym czasem trwania do nowej skali zoomu.

Takie podejście nie jest eleganckie, ale działa. Oto kod, aby dostać się zaczęło:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView 
{ 
    CGFloat zoomScale = _scrollView.zoomScale; 

    CALayer *layer = _contentView.layer; 
    NSArray *animationKeys = [layer animationKeys]; 

    if (animationKeys.count == 0) { 
     // set zoomScale on target view 
    } else { 
     CFTimeInterval duration = 0.0; 
     for (NSString *animationKey in animationKeys) { 
      CAAnimation *animation = [layer animationForKey:animationKey]; 
      duration = animation.duration; 
      break; 
     } 
     // easeInEaseOut is the default animation when the zoom bounces 
     [UIView animateWithDuration:duration delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ 
      // set zoomScale on target view 
     } completion:nil]; 
    } 
} 
+0

To wygląda obiecująco. Czy możesz wyjaśnić, dlaczego przechowujesz _previousZoomScale? Nie widzę, żeby był używany gdziekolwiek. – combinatorial

+0

Dobrze, w moim projekcie testowym zapisałem zarówno starą, jak i nową wartość, ale jeśli ustawisz zoom na innym obiekcie, potrzebujesz tylko nowej wartości. Będę się dostosowywać, może odpowiedzieć odpowiednio. –

Powiązane problemy