UIView在显示/隐藏键盘上使用动画内容阻止动画过渡
在我的应用程序中,我在某个视图上有一个文本字段,键盘在显示时会被覆盖。 所以我必须滚动视图(甚至重新排列子视图)。 要做到这一点我:
-
注册键盘通知:
[[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
情况下模拟模态行为(为什么会这样? 也许它只是一个糟糕的设计,我会发布另一个问题 )。
那么为什么在这种情况下, moveViewDown
方法的动画不会在适当的时候触发?
更新1
我为每个函数添加了一个调试打印来检查调用的顺序,这就是我得到的:
-[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]; }
我得到完全相同的日志。
更新2
我已经进行了一些实验并做出了以下结论:
- 如果我显式地调用
moveViewDown
或resignFirstResponder:
动画被推迟到当前运行循环结束,此时所有挂起的动画实际上都开始播放。 虽然动画块立即登录到控制台 – 对我来说似乎很奇怪! - 方法
transitionFromView:toView:duration:options:completion:
也许transitionWithView:duration:options:animations:completion:
也是,没有检查这个)显然是制作了“from-view”和“to-view”的快照“并仅使用这些快照创建动画。 由于视图的滚动被推迟,因此在视图仍然偏移时进行快照。 该方法甚至忽略了UIViewAnimationOptionAllowAnimatedContent
选项 。 - 我设法使用任何
animateWithDuration: ... completion:
获得所需的效果animateWithDuration: ... completion:
方法。 这些方法似乎忽略了UIViewAnimationOptionTransitionFlipFromRight
等转换选项 。 - 键盘开始隐藏(隐式)并在调用
removeFromSuperview
时发送相应的通知。
如果我错了,请纠正我。
如果你试图在没有UIViewController
情况下模拟模态行为,我猜你想让你的下一个视图从屏幕底部出现吗? 如果我错了,请纠正我。 如果你想要这样一个动画你可以尝试一个解决方法,你可以在animation
块中更改下一个视图的框架,使其看起来好像它与presentModalViewController
类似
- 如何在heightForRowAtIndexPath中获取UITableViewCell?
- 操作手势后从UIImageView保存图像
- 用完成块来呈现和解除UIViewController – 没有协议和委托
- 仅限于iPhone 5 / 5s / 5c的用户将AppStore的应用程序安装限制在内
- 我们应该使用哪些iOS设备进行合理的function和性能testing?
- 如何检查IOS中的networking2G或3G?
- 检查推送通知注册:isRegisteredForRemoteNotifications不更新
- 如何在UITextField成为第一响应者时进行UIScrollView自动滚动
- 同一个iDevice可以通过蓝牙进行通信吗?