【问题标题】:UIView block animation transitions with animated content on showing/hiding keyboardUIView 在显示/隐藏键盘上使用动画内容阻止动画过渡
【发布时间】:2011-08-08 19:48:19
【问题描述】:

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

  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];
    
    }
    

这很好用,视图会上下滚动,直到我添加更多动画。具体来说,当用户点击按钮时,我正在添加到下一个视图的过渡:

- (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:,没有检查这个)显然会制作“from-view”和“to-view”的快照,并仅使用这些快照创建动画。由于视图的滚动被推迟,因此在视图仍然偏移时进行快照。该方法以某种方式甚至忽略了UIViewAnimationOptionAllowAnimatedContent 选项
  3. 我设法使用任何animateWithDuration: ... completion: 方法获得了预期的效果。这些方法似乎忽略了转换选项,例如UIViewAnimationOptionTransitionFlipFromRight
  4. 键盘开始隐藏(隐式)并在调用removeFromSuperview 时发送相应的通知。

如果我在某处错了,请纠正我。

【问题讨论】:

  • 我认为,当您处于视图动画之间时,您会收到键盘关闭通知。两个动画可能相互冲突,结果是视图失真。
  • @Jhaliya,请查看更新后的问题
  • 澄清一下:我确实在视图动画之间收到了通知,但是它不会使动画冲突或扭曲视图。我不介意你投票,但@Jhaliya 不正确。

标签: iphone ios animation uiview keyboard


【解决方案1】:

如果您尝试在没有UIViewController 的情况下模拟模态行为,我猜您希望下一个视图从屏幕底部显示,对吧?如果我错了,请纠正我。 如果你想要这样的动画,你可以尝试一种变通方法,在 animation 块中更改下一个视图的框架,使其看起来类似于 presentModalViewController

【讨论】:

  • 是的,你是对的。我可以再次使用animateWithDuration:animations: 并制作类似 self.nextView.origin.y = window.y 的东西,然后在动画块self.nextView.origin.y = 0 中(当然这不会编译,认为它是伪代码)。这是模态视图的默认行为,尽管还有其他UIModalTransitionStyles,包括UIModalTransitionStyleFlipHorizontal。但这并没有解决问题,而且还增加了更多的复杂性。
  • 尝试在视图动画关闭后延迟调用函数
  • 对不起,我的错。你是对的。请检查更新的问题,也许您可​​以添加一些其他注意事项。
猜你喜欢
  • 1970-01-01
  • 2019-01-16
  • 2012-02-25
  • 1970-01-01
  • 2021-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多