UIView在显示/隐藏键盘上使用动画内容阻止动画过渡

时间:2011-04-19 16:05:21

标签: iphone ios animation uiview keyboard

在我的应用程序中,我在某个视图上有一个文本字段,当键盘出现时会被键盘覆盖。所以我必须滚动视图(甚至重新排列子视图)。要做到这一点我:

  1. 注册键盘通知:

    [[NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(moveViewUp)
                                          name:UIKeyboardWillShowNotification
                                          object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                          selector:@selector(moveViewDown)
                                          name:UIKeyboardWillHideNotification
                                          object:nil];
    
  2. 收到通知后,使用以下块动画移动视图:

    - (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];
    
    }
    
  3. 这很好用,视图上下滚动,直到我添加更多动画。具体来说,当用户点击按钮时,我正在向下一个视图添加转换:

    - (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方法的动画不会在适当的时间触发?

    更新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

    我已经进行了一些实验并做出了以下结论:

    1. 如果我明确地调用moveViewDownresignFirstResponder:,则动画将推迟到当前运行循环结束,此时所有待处理的动画实际开始播放。虽然动画块会立即登录到控制台 - 对我来说似乎很奇怪!
    2. 方法transitionFromView:toView:duration:options:completion:(也许transitionWithView:duration:options:animations:completion:也没有检查过这个)显然会创建“从视图”和“到视图”的快照并使用这些创建动画仅限快照。由于视图的滚动被推迟,因此在视图仍然偏移时创建快照。该方法以某种方式忽略了UIViewAnimationOptionAllowAnimatedContent选项
    3. 我设法使用任何animateWithDuration: ... completion:方法获得了预期的效果。这些方法似乎忽略转换选项,例如UIViewAnimationOptionTransitionFlipFromRight
    4. 键盘开始隐藏(隐式)并在调用removeFromSuperview时发送相应的通知。
    5. 如果我错了,请纠正我。

1 个答案:

答案 0 :(得分:0)

如果你试图在没有UIViewController的情况下模拟模态行为,我猜你想让你的下一个视图从屏幕底部出现吗?如果我错了,请纠正我。 如果您想要这样的动画,您可以尝试在animation块中更改下一个视图的框架,以使其看起来像presentModalViewController