Czy nslayoutconstraints można animować? [duplikat]
To pytanie ma już odpowiedź tutaj:
- jak animować zmiany ograniczeń? 13 Odpowiedzi
Staram się animować niektóre widoki tak, aby były blokowane przez gigantyczną klawiaturę w krajobrazie. To działa dobrze, jeśli po prostu animować klatki, ale inni sugerują, że jest to przeciwne do produktywności i powinienem być aktualizowanie Zamiast tego NSLayoutConstraints. Jednak nie wydają się być animowane. Czy ktoś namówił ich do pracy z sukcesem?
//heightFromTop is an NSLayoutConstraint referenced from IB
[UIView animateWithDuration:0.25 animations:^{
self.heightFromTop.constant= 550.f;
}];
Rezultatem jest natychmiastowy skok na daną wysokość.
4 answers
Po prostu postępuj zgodnie z tym wzorem:
self.heightFromTop.constant = 550.0f;
[myView setNeedsUpdateConstraints];
[UIView animateWithDuration:0.25f animations:^{
[myView layoutIfNeeded];
}];
Gdzie myView
jest widokiem, do którego dodano self.heightFromTop
. Twój widok jest "skokowy", ponieważ jedyną rzeczą, którą zrobiłeś w bloku animacji, było ustawienie ograniczenia, co nie powoduje natychmiastowych układów. W kodzie układ występuje w następnej pętli run Po ustawieniu heightFromTop.constant
i do tego czasu jesteś już poza zakresem bloku animacji.
W Języku Swift 2:
self.heightFromTop.constant = 550
myView.setNeedsUpdateConstraints()
UIView.animateWithDuration(0.25, animations: {
myView.layoutIfNeeded()
})
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-03 15:55:53
Sugerowany przez Apple sposób jest nieco inny (Zobacz przykład w sekcji "animowanie zmian dokonanych przez układ Automatyczny" ). Najpierw musisz wywołać layoutIfNeeded przed animacją. Następnie dodaj swoje animacje wewnątrz bloku animacji, a następnie ponownie wywołaj layoutIfNeeded na końcu. Dla facetów takich jak ja, którzy przechodzą do autolayout, jest to bardziej podobny sposób do poprzednich animacji, które robiliśmy z klatkami wewnątrz bloków animacji. Musimy tylko zadzwonić do layoutIfNeeded dwa razy-przed animacjami i po animacjach:
[self.view layoutIfNeeded]; // Ensures that all pending layout operations have been completed
[UIView animateWithDuration:1.0f animations:^{
// Make all constraint changes here
self.heightFromTop.constant= 550.f;
[self.view layoutIfNeeded]; // Forces the layout of the subtree animation block and then captures all of the frame changes
}];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-23 11:22:58
Próbowałem podejścia @ Centurion, ale jakoś mój widok animuje się do złej klatki, jeśli jest załadowany z storyboardu. Problem zniknie, jeśli zamienię pierwszą layoutIfNeeded
na updateConstraintsIfNeeded
, choć nie mam pojęcia dlaczego. Jeśli ktoś może dać wyjaśnienie, byłoby to bardzo mile widziane.
[self.view updateConstraintsIfNeeded];
[UIView animateWithDuration:1.0 animations:^{
self.myConstraint.constant= 100;
[self.view layoutIfNeeded];
}];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-24 00:59:05
Miałem podobny problem i ten wątek był bardzo pomocny, aby go ominąć.
Odpowiedź od erurainon postawiła mnie na dobrej drodze, ale chciałbym zaproponować nieco inną odpowiedź. Sugerowany kod z erurainon nie działał dla mnie, ponieważ nadal miałem skok zamiast animowanego przejścia. Link podany przez cnotethegr8 dał mi działającą odpowiedź:
Auto Layout Przewodnik https://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/AutolayoutPG/AutoLayoutbyExample/AutoLayoutbyExample.html (na samym dole strony).
Kilka różnic od odpowiedzi erurainona:
- wywołanie layoutIfNeeded w widoku kontenera przed wywołaniem metody animacji (i zamiast setNeedsUpdateConstraints w myView).
- Ustaw nowe ograniczenie w animacjach blok.
- wywołanie layoutIfNeeded w widoku kontenera w metodzie animations (po ustawieniu ograniczenia), zamiast w myView.
Będzie to zgodne ze wzorem sugerowanym przez Apple w linku powyżej.
Przykład
Chciałem animować konkretny widok, zamykając go lub rozszerzając jednym kliknięciem. Ponieważ używam autolayout i nie chcę kodować żadnych wymiarów (w moim przypadku wysokość) w kodzie, postanowiłem uchwycić wysokość in viewDidLayoutSubviews. Musisz użyć tej metody, a nie viewWillAppear podczas korzystania z autolayout. Ponieważ viewDidLayoutSubviews może być wywoływany wiele razy, użyłem BOOL, aby dać mi znać o pierwszym uruchomieniu dla mojej inicjalizacji.
// Code snippets
@property (weak, nonatomic) IBOutlet UIView *topView; // Container for minimalView
@property (weak, nonatomic) IBOutlet UIView *minimalView; // View to animate
@property (nonatomic) CGFloat minimalViewFullHeight; // Original height of minimalView
@property (weak, nonatomic) IBOutlet NSLayoutConstraint *minimalViewHeightConstraint;
@property (nonatomic) BOOL executedViewDidLayoutSubviews;
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
// First execution of viewDidLayoutSubviews?
if(!self.executedViewDidLayoutSubviews){
self.executedViewDidLayoutSubviews = YES;
// Record some original dimensions
self.minimalViewFullHeight = self.minimalView.bounds.size.height;
// Setup our initial view configuration & let system know that
// constraints need to be updated.
self.minimalViewHeightConstraint.constant = 0.0;
[self.minimalView setNeedsUpdateConstraints];
[self.topView layoutIfNeeded];
}
}
Resize full action snippet
// An action to close our minimal view and show our normal (full) view
- (IBAction)resizeFullAction:(UIButton *)sender {
[self.topView layoutIfNeeded];
[UIView transitionWithView:self.minimalView
duration:1.0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.minimalViewHeightConstraint.constant = 0.0;
// Following call to setNeedsUpdateConstraints may not be necessary
[self.minimalView setNeedsUpdateConstraints];
[self.topView layoutIfNeeded];
} completion:^(BOOL finished) {
;
}];
// Other code to show full view
// ...
}
Resize small action snippet
// An action to open our minimal view and hide our normal (full) view
- (IBAction)resizeSmallAction:(UIButton *)sender {
[self.topView layoutIfNeeded];
[UIView transitionWithView:self.minimalView
duration:1.0
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{
self.minimalViewHeightConstraint.constant = self.minimalViewFullHeight;
[self.minimalView setNeedsUpdateConstraints];
[self.topView layoutIfNeeded];
} completion:^(BOOL finished) {
;
}];
// Other code to hide full view
// ...
}
Jeśli chcesz, możesz użyć programu animateWithDuration zamiast transitionWithView.
Mam nadzieję, że to pomoże.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-01 19:49:44