第一次显示 View Controller 的 View 时,我想运行一个动画,其中 View Controller 中的所有元素都从屏幕底部之外滑动到其自然位置。为此,我在subview.frame.origin.y += self.view.frame.size.height
中执行viewDidLayoutSubviews
。我也尝试过viewWillAppear
,但是它根本不起作用。然后,用subview.frame.origin.y -= self.view.frame.size.height
中的viewDidAppear
将它们设置到自然位置。
问题在于,在 View Controller 的整个生命周期中,多次调用了viewDidLayoutSubviews
。这样,当发生诸如显示键盘之类的事情时,我所有的内容都会再次在 View 外部被替换。
有更好的方法吗?我是否需要添加某种标志来检查动画是否已经运行?
编辑:这是代码。在这里,我在prepareAppearance
中调用了viewDidLayoutSubviews
,它起作用了,但是在 Controller 的整个生命周期中,多次调用了viewDidLayoutSubviews
。
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[self prepareAppearance];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self animateAppearance];
}
- (NSArray *)animatableViews
{
return @[self.createAccountButton, self.facebookButton, self.linkedInButton, self.loginButton];
}
- (void)prepareAppearance
{
NSArray * views = [self animatableViews];
NSUInteger count = [views count];
for (NSUInteger it=0 ; it < count ; ++it) {
UIView * view = [views objectAtIndex:it];
CGRect frame = view.frame;
// Move the views outside the screen, to the bottom
frame.origin.y += self.view.frame.size.height;
[view setFrame:frame];
}
}
- (void)animateAppearance
{
NSArray * views = [self animatableViews];
NSUInteger count = [views count];
for (NSUInteger it=0 ; it < count ; ++it) {
__weak UIView * weakView = [views objectAtIndex:it];
CGRect referenceFrame = self.view.frame;
[UIView animateWithDuration:0.4f
delay:0.05f * it
options:UIViewAnimationOptionCurveEaseOut
animations:^{
CGRect frame = weakView.frame;
frame.origin.y -= referenceFrame.size.height;
[weakView setFrame:frame];
}
completion:^(BOOL finished) {
}];
}
}
最佳答案
如果需要在显示 View 时设置动画,然后在以后不触摸 subview ,则建议以下操作:
viewDidLayoutSubviews
viewWillAppear
viewDidAppear
中的适当位置UPDATE :
如果您使用的是自动布局(这是很好的事情),则无法通过直接更改其框架来为 View 设置动画(因为自动布局会忽略并再次更改它们)。您需要做的是将导出暴露于负责Y位置的约束(在您的情况下),并更改该约束而不是设置框架。
另外,在更新animation方法中的约束后,请不要忘记包含对
[weakView layoutIfNeeded]
的调用。