2013-03-17 11 views
7

Próbuję utworzyć animację w mojej aplikacji na iOS, gdzie nowy widok przesuwa się po ekranie od lewej, a widok główny przesuwa się w prawo, aby zrobić dla niego miejsce. Widok główny jest widokiem z góry widoku z góry mojego kontrolera widoku, a widok boczny, który się ślizga, jest ładowany z oddzielnego pliku XIB.Próbuję jednocześnie animować dwa UIView, tylko jeden przesuwa

W przypadku jest to istotne, tu jest mój kod do załadowania widoku z boku, zwany od viewDidLoad sposobu mojego głównego sterownika widok na:

sideViewController = [[SideViewController alloc] init]; 
[sideViewController loadView]; 

sideView = sideViewController.topView; 
[self.view addSubview:sideView]; 
sideView.hidden = YES; 
sideView.frame = CGRectMake(-200, 0, 200, 460); 

A oto kod, który zostaje wezwany do animowania dwa widoki:

sideView.hidden = NO; 
[UIView animateWithDuration:0.25f 
       animations:^{       
        mainView.frame = CGRectMake(200, 0, 320, 460); 
        sideView.frame = CGRectMake(0, 0, 200, 460); 
       }]; 

Wydaje się to dość proste. Ale z jakiegoś powodu tylko animacje sideView - mainView nigdzie się nie porusza. Aby jeszcze bardziej zagmatwać rzeczy, jeśli skomentuję wiersz bloku animacji, który przesuwa sideView, animacja mainView zacznie działać.

Czy ktoś wie, co jest nie tak? Ze wszystkich wyszukiwań i dokumentów, które przeczytałem, to, co robię, powinno działać dobrze. To, co myślałem, że będzie prostą animacją, zmieniło się w godziny frustracji. Każda pomoc będzie doceniona!

Edit:

Pisali sugestii Guo Luchuan za Próbowałem animowanie różne właściwości dwóch UIViews. Większość uzyskała taki sam wynik, chociaż pracowała nad animacją obu ich właściwości przekształcania. W takim przypadku oba UIViews były animowane, ale mainView zrobił coś złego: animacja zaczęła się od niego w innej pozycji i kończyła w niewłaściwym miejscu. To wygląda jakby wykonując tłumaczenie poleciłem to zrobić, ale zaczynając od tego stanowiska wyrażonego w obliczeniach wektorowej:

starting_point - 0.5 * total_translation 

co oznacza, że ​​kończy się na:

starting_point + 0.5 * total_translation 

boczne, jednak ożywia poprawnie.

To jest cholernie irytujące. Nie zdawałem sobie sprawy, że animacje wykonawcze na iOS są w ten sposób zepsute. Następną rzeczą, którą zamierzam wypróbować, jest użycie CABasicAnimation, chociaż jestem nieszczęśliwa, muszę uciekać się do wypróbowania tak niskiego poziomu API dla czegoś tak prostego.

Odpowiedz

3

Problem polegał na tym, że dla moich plików xib miałem włączoną autoreferencję. Gdy tylko go wyłączyłem, mój oryginalny kod animacji działał bezbłędnie.

+0

Miałem ten sam problem, a także miałem włączone autoLayout. Wyłączenie tego niestety mi nie pomogło ... chociaż mogłem przegapić miejsce, w którym wyłączyłeś je globalnie (buduję ekrany z kodem). Jednym z rozwiązań, które znalazłem, było osadzenie obu widoków w widoku kontenera nadrzędnego i po prostu animacja tego. – avance

4

Spotkałem ten sam problem jak ty.

Kiedy zestaw 2 widoki same właściwości (jak frame lub transform) w tym samym czasie, w UIView animation block, to nie będzie działać, czego się spodziewać.

Tak więc ustawiam widoki frame i ustawię kolejne widoki transform, to działa dobrze, ale nie wiem, dlaczego tak będzie.

Myślę, że to zadziała dobrze dla ciebie.

sideView.hidden = NO; 
[UIView animateWithDuration:0.25f 
       animations:^{       
        mainView.frame = CGRectMake(200, 0, 320, 460); 
        sideView.transform = CGAffineTransformMakeTranslation(200,0); 
       }]; 

I myślę, że można zrobić 2 CABasicAnimation a następnie dodać je do CAAnimationGroup.To również może pracować dla Ciebie

+0

To świetna propozycja, chociaż spróbowałem i nie zadziałało. Naprawdę próbowałem animować kilka różnych kombinacji atrybutów i albo otrzymałem taki sam wynik, albo inny niewłaściwy wynik. Zamierzam edytować mój główny post, aby dowiedzieć się więcej. – GuyGizmo

0

Jeśli sideView jest subview z mainView użyć tej metody animacji:

+animateWithDuration:delay:options:animations:completion: 

z opcją:

UIViewAnimationOptionAllowAnimatedContent 
+0

sideView i mainView są rodzeństwem pod moim widokiem kontrolera widoku, więc nie powinno to mieć zastosowania. Jednak dziwne jest to, że sideView wyraźnie wpływa na mainView w dziwny sposób, którego nie rozumiem, więc mimo to spróbowałem użyć tej opcji, ale to nie miało znaczenia. – GuyGizmo

+0

Przepraszam, przeczytałem twoją Q złą. Jeśli są rodzeństwem, nie wiem, co się z tobą dzieje. – Tricertops

0

końcu znalazłem rozwiązanie, a Myślę, że to bardzo haniebne. Oto kod, który działa:

mainView.transform = CGAffineTransformMakeTranslation(400,0); 
CABasicAnimation *move = [CABasicAnimation animationWithKeyPath:@"transform.translation.x" ]; 
[move setFromValue:[NSNumber numberWithFloat:200]]; 
[move setToValue:[NSNumber numberWithFloat:400]]; 
[move setDuration:0.25]; 
move.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
[[mainView layer] addAnimation:move forKey:@"transform.translation.x"]; 

sideView.center = CGPointMake(100, 230); 
CABasicAnimation *sideMove = [CABasicAnimation animationWithKeyPath:@"transform.translation.x" ]; 
[sideMove setFromValue:[NSNumber numberWithFloat:-200]]; 
[sideMove setToValue:[NSNumber numberWithFloat:0]]; 
[sideMove setDuration:0.25]; 
sideMove.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]; 
[[sideView layer] addAnimation:sideMove forKey:@"transform.translation.x"]; 

Po pierwsze, jeśli nie ustawić MAINVIEW na przekształcać, cała ta sprawa nie będzie działać i MAINVIEW nie ruszy nigdzie po animacja została wykonana. Próbowałem ustawić jego ramkę i środek, ale żadne z nich nie miało żadnego efektu. Tylko transformacja działała. Ten szczegół jest podobny do użycia metody animateWithDuration.

Po drugie, i to jest ta część, która mnie najbardziej zdezorientowała, dlaczego liczby są tym, czym są? Z jakiegoś powodu musiałem przesunąć mainView o dodatkowe 200 pikseli w prawo (szerokość sideView), aby odpowiednio ustawić linię. Gdybym tego nie zrobił, animowałbym dokładnie tam, gdzie kiedyś był, mimo że zmieniałem jego afiniczną transformację z tożsamości na tłumaczenie z 200 pikseli na prawo.

Tak blisko, jak mogę stwierdzić, sideView ma wpływ na mainView w jakiś dziwny sposób, mimo że są one rodzeństwa bezpośrednio pod moim widokiem kontrolera na najwyższym poziomie, i nie powinien mieć żadnego rodzaju hierarchicznej relacji. Zgaduję, że ma to coś wspólnego z ładowaniem sideView z Xib, ale o ile wiem, robię to poprawnie.

Mamy nadzieję, że to rozwiązanie przyda się komuś, kto znajdzie się w podobnej sytuacji i nie będzie musiał robić tego samego irytującego programowania martwego kurczaka, co właśnie zrobiłem.

Ponadto, jeśli ktoś może zaoferować wyjaśnienie tego wszystkiego, byłbym bardzo wdzięczny! Nie lubię kodowania rzeczy, których nie rozumiem, i bardzo chciałbym się dowiedzieć, dlaczego tak się stało, więc mogę uniknąć takich sytuacji w przyszłości.

+1

Prawdziwy Q jest, ** dlaczego ** to nie działa w prosty sposób? Jeśli możesz powiedzieć mi więcej rzeczy: skąd dzwonisz do animacji? Czy używasz autorezoryzacji lub automatycznego układu w kodzie i XIB? – Tricertops

+2

O Boże, cały problem polegał na tym, że włączono autolayout. Nie po raz pierwszy popełniłem ten błąd, ale zapomniałem o tym, dopóki o tym nie wspomniałeś. Właśnie wyłączyłem go na obu moich plikach xib i nagle animacjaWithDuration działa idealnie. Godziny mojego czasu zostały właśnie utracone z powodu tej cechy i nic nie wskazywało na to, że to był winowajca. – GuyGizmo

+0

Tak, podczas korzystania z automatycznego układu nie modyfikuje się bezpośrednio ramek. Nie próbowałem animacji w Auto układu, ale może można animować "stałe" ograniczeń. – Tricertops

Powiązane problemy