UIView的显示/隐藏键盘上阻止动画过渡与动画内容 [英] UIView block animation transitions with animated content on showing/hiding keyboard
问题描述
在我的应用我有一些人认为这是由键盘覆盖时,它显示了一个文本字段。所以我要滚动视图(甚至重新排列子视图)。要做到这一点我:
In my app I have a text field on some view which is covered by the keyboard when it shows up. So I have to scroll the view (or even rearrange the subviews). To do this I:
-
注册键盘的通知:
register for keyboard notifications:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(moveViewUp)
name:UIKeyboardWillShowNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(moveViewDown)
name:UIKeyboardWillHideNotification
object:nil];
在接到通知时,使用块动画这样的移动视图:
upon receiving a notification, move the view using block animations like this:
- (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];
}
这工作得很好,认为向上和向下滚动,直到我添加一些更多的动画。特别是当用户点击一个按钮,我加入到下一个视图的转换:
This works fine, the view scrolls up and down, until I add some more animation. Specifically I'm adding a transition to a next view when the user taps a button:
- (IBAction)switchToNextView:(id)sender {
// [self presentModalViewController:nextViewController animated:YES];
[UIView transitionFromView:self.view
toView:self.nextView
duration:1.0
options:UIViewAnimationOptionTransitionFlipFromRight
completion:nil];
}
现在我们到了这个问题。结果
如果当按钮被窃听的第一个视图被转移(这意味着,键盘是可见的),到下一个视图的转换同时开始为键盘滑下,但视图本身的不下移,所以一秒钟,我们可以清楚地看到下面的视图。那是不对的。当我present下一个视图模态(见注释行)所有动画去,因为我希望他们:即键盘隐藏,视图是由右的翻转和的向下滚动 - 所有与此同时。这将是很好,但问题是,我居然没有一个的UIViewController
该视图。其实我试图模拟无的UIViewController
的模态行为(为什么这样?的也许这只是一个糟糕的设计,我会后在该另一个问题)。
Now we got to the problem.
If the first view was shifted when the button was tapped (that means that the keyboard was visible), the transition to the next view starts simultaneously as the keyboard slides down, but the view itself doesn't move down, so for a split second we can actually see the underlying view. That's not right. When I present the next view modally (see the commented line) all animations go as I want them to: i.e. the keyboard is hiding, the view is flipping from right and scrolling down -- all at the same time. This would be fine, but the problem is that I actually don't have a UIViewController
for that view. In fact I'm trying to simulate the modal behavior without UIViewController
(why so? perhaps it's just a bad design, I'll post another question on that).
那么,为什么在这种情况下,从 moveViewDown
方法不是在适当的时候触发?动画
So why does in this case the animation from moveViewDown
method is not triggered at the proper time?
我添加了一个调试打印每个功能检查调用的顺序,这是我得到:
I added a debug print to each function to check the order of calling, this is what I get:
-[KeyboardAnimationViewController moveViewUp]
__-[KeyboardAnimationViewController moveViewUp]_block_invoke_1 <-- scroll up animation
-[KeyboardAnimationViewController switchToNextView:]
-[KeyboardAnimationViewController moveViewDown]
__-[KeyboardAnimationViewController moveViewDown]_block_invoke_1 <-- scroll down animation
即使我明确地这样的转换之前移动视图下
Even if I explicitly move the view down before the transition like this
- (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];
}
我得到的究竟的相同的日志。
我已经试验多一些,并提出如下结论:
I've experimented some more and made following conclusions:
- 如果我称之为
moveViewDown
或resignFirstResponder:
明确,动画被推迟到当前运行循环结束,当所有未决的动画居然开始播放。虽然马上动画块日志到控制台 - 觉得奇怪,我 ! - 的方法
transitionFromView:toView:持续时间:选择:完成:
(也许transitionWithView:时间:选择:动画:完成:
也没有检查这一项)显然使的从视图快照和为视角,并创建使用这些快照仅动画。由于视图的滚动被推迟,当视图仍然偏移快照制成。该方法在某种程度上的忽略甚至UIViewAnimationOptionAllowAnimatedContent
选项 - 我设法使用任何
的animateWithDuration预期的效果:...完成:
方法。这些方法似乎不顾过渡选项如UIViewAnimationOptionTransitionFlipFromRight
。 - 键盘隐藏启动(隐含的),并发送相应的通知时,
removeFromSuperview
被调用。
- If I call
moveViewDown
orresignFirstResponder:
explicitly, the animation is postponed until the end of current run loop, when all pending animations actually start to play. Though the animation block logs to the console immediately -- seems strange to me! - The method
transitionFromView:toView:duration:options:completion:
(perhapstransitionWithView:duration:options:animations:completion:
too, didn't check this one) apparently makes a snapshot of the "from-view" and the "to-view" and creates an animation using these snapshots solely. Since the scrolling of the view is postponed, the snapshot is made when the view is still offset. The method somehow disregards even theUIViewAnimationOptionAllowAnimatedContent
option. - I managed to get the desired effect using any of
animateWithDuration: ... completion:
methods. These methods seems to disregard transition options likeUIViewAnimationOptionTransitionFlipFromRight
. - The keyboard starts hiding (implicitly) and sends corresponding notification when
removeFromSuperview
is called.
如果我错了地方请大家指正。
Please correct me if I'm wrong somewhere.
推荐答案
如果你试图模拟无的UIViewController
模态行为,我想你想你的下一个视图来显示从屏幕右侧的底部?纠正我,如果我错了。
如果你想这样的动画,你可以尝试一个变通,你改下视图的动画中的帧
块,使得它看起来好像它类似于 presentModalViewController
If you are trying to simulate the modal behavior without UIViewController
I guess you want your next view to show up from the bottom of the screen right?. correct me if I am wrong.
If you want such an animation you can try a work-around where you change the frame of the next view within an animation
block such that it appears as if its similar to presentModalViewController
这篇关于UIView的显示/隐藏键盘上阻止动画过渡与动画内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!