在我的应用程序中,我在某个视图上有一个文本字段,当键盘出现时会被键盘覆盖。所以我必须滚动视图(甚至重新排列子视图)。要做到这一点我:
注册键盘通知:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(moveViewUp)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(moveViewDown)
name:UIKeyboardWillHideNotification
object:nil];
收到通知后,使用以下块动画移动视图:
- (void)moveViewUp {
void (^animations)(void) = nil;
oldViewFrame = self.view.frame;
animations = ^{
CGRect newViewFrame = oldViewFrame;
newViewFrame.origin.y -= kViewOffset;
self.view.frame = newViewFrame;
};
[UIView animateWithDuration:1.0
animations:animations];
}
- (void)moveViewDown {
void (^animations)(void) = nil;
animations = ^{
self.view.frame = oldViewFrame;
};
[UIView animateWithDuration:1.0
animations:animations];
}
这很好用,视图上下滚动,直到我添加更多动画。具体来说,当用户点击按钮时,我正在向下一个视图添加转换:
- (IBAction)switchToNextView:(id)sender {
// [self presentModalViewController:nextViewController animated:YES];
[UIView transitionFromView:self.view
toView:self.nextView
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
}
现在我们遇到了问题
如果在点击按钮时移动了第一个视图(这意味着键盘可见),当键盘向下滑动时,转换到下一个视图会同时开始,但视图本身不会向下移动,所以一瞬间我们实际上可以看到底层视图。那是不对的。当我以模态方式呈现下一个视图时(请参阅注释行),所有动画都按照我的要求进行:即键盘隐藏,视图从右侧和向下滚动 - 所有这些都在同一时间时间。这没关系,但问题是我实际上没有UIViewController
的视图。事实上,我试图模拟没有UIViewController
的模态行为(为什么会这样?perhaps it's just a bad design, I'll post another question on that)。
那么为什么在这种情况下,moveViewDown
方法的动画不会在适当的时间触发?
我为每个函数添加了一个调试打印,以检查调用的顺序,这就是我得到的:
-[KeyboardAnimationViewController moveViewUp]
__-[KeyboardAnimationViewController moveViewUp]_block_invoke_1 <-- scroll up animation
-[KeyboardAnimationViewController switchToNextView:]
-[KeyboardAnimationViewController moveViewDown]
__-[KeyboardAnimationViewController moveViewDown]_block_invoke_1 <-- scroll down animation
即使我在转换之前明确地移动视图,如此
- (IBAction)switchToNextView:(id)sender {
// [self presentModalViewController:nextViewController animated:YES];
NSLog(@"%s", __PRETTY_FUNCTION__);
if (self.view.frame.origin.x < 0)
[self moveViewDown];
[UIView transitionFromView:self.view
toView:self.nextView
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
}
我完全相同的日志。
我已经进行了一些实验并做出了以下结论:
moveViewDown
或resignFirstResponder:
,则动画将推迟到当前运行循环结束,此时所有待处理的动画实际开始播放。虽然动画块会立即登录到控制台 - 对我来说似乎很奇怪! transitionFromView:toView:duration:options:completion:
(也许transitionWithView:duration:options:animations:completion:
也没有检查过这个)显然会创建“从视图”和“到视图”的快照并使用这些创建动画仅限快照。由于视图的滚动被推迟,因此在视图仍然偏移时创建快照。该方法以某种方式忽略了UIViewAnimationOptionAllowAnimatedContent
选项。animateWithDuration: ... completion:
方法获得了预期的效果。这些方法似乎忽略转换选项,例如UIViewAnimationOptionTransitionFlipFromRight
。removeFromSuperview
时发送相应的通知。如果我错了,请纠正我。
答案 0 :(得分:0)
如果你试图在没有UIViewController
的情况下模拟模态行为,我猜你想让你的下一个视图从屏幕底部出现吗?如果我错了,请纠正我。
如果您想要这样的动画,您可以尝试在animation
块中更改下一个视图的框架,以使其看起来像presentModalViewController