首页 文章

在iOS7中向后滑动边缘时,使键盘与UIView同步动画

提问于
浏览
25

我想在iOS7中获得类似于Messages app(在大多数短信应用程序中也很常见)的行为,其中在对话视图中从屏幕左边缘向右滑动将表现得像UINavigationController中的后退按钮 .

我已设法实现此行为,但是,如果键盘在呈现视图中打开,当我开始向后滑动时,键盘会卡住,并且在我移动手指时不会使视图向右移动 . 我想将键盘和呈现视图设置为一个单元,而不是将键盘放在其他视图的顶部,并且它们在它后面动画,这就是我现在所获得的(请参阅第二个屏幕截图):

UPDATE: 请注意,主视图动画完成后键盘最终会消失;我关注的是键盘的位置 during 滑动过程,当你持续触摸设备的一半时,这是不同步的用实际视图 . 第二个屏幕截图澄清了这个想要的行为 . 我也想知道为什么它不是默认行为 . )

只需在Xcode 5.0.2中创建一个新的主 - 细节iPhone应用程序,并在StoryBoard中为详细视图(最好是上半部分的某个地方)添加一个文本字段,运行应用程序,添加项目,就可以轻松复制问题 . ,点击它以转到详细视图并单击您添加的文本字段 . 从设备左侧边缘滑动,同时将手指放在上面,您将看到问题 .

期望的行为:

Desired behavior

目前的行为:

Keyboard tearing

3 回答

  • 2

    不幸的是,没有内置的方法来做到这一点 . 我真的希望有 UIScrollViewKeyboardDismissModeInteractiveUIViewController s .

    现在,要在viewControllers之间进行任何动画,你应该使用transitionCoordinator

    - (BOOL)animateAlongsideTransition:(void (^)(id <UIViewControllerTransitionCoordinatorContext>context))animation
                            completion:(void (^)(id <UIViewControllerTransitionCoordinatorContext>context))completion;
    
    - (BOOL)animateAlongsideTransitionInView:(UIView *)view
                                   animation:(void (^)(id <UIViewControllerTransitionCoordinatorContext>context))animation
                                  completion:(void (^)(id <UIViewControllerTransitionCoordinatorContext>context))completion;
    

    对于键盘,你应该这样做:

    [self.transitionCoordinator animateAlongsideTransitionInView:self.keyboardSuperview
                                                       animation:
    ^(id<UIViewControllerTransitionCoordinatorContext> context) {
        self.keyboardSuperview.x = self.view.width;
    }
                                                      completion:nil];
    

    至于 keyboardSuperview - 您可以通过创建假 inputAccessoryView 来获得:

    self.textField.inputAccessoryView = [[UIView alloc] init];
    

    那么superview将是 self.textField.inputAccessoryView.superview

  • 12

    它应该自动工作,但有时它不会因某些条件而起作用 .

    如果当前 firstResponder 位于活动 UIViewController 内并且在整个 UINavigationController 机制中消失,则将自动执行预期的键盘动画(水平) . 因此,有时这种默认行为会受到其他奇怪因素的影响,键盘开始消失,而不是水平动画 .

    我花了几天调试内部UIKit的东西(围绕方法 needDeferredTransitionallowCustomTransition 和其他)来找到一个在我的情况下扮演关键角色的特殊因素 .

    我发现 UIPeripheralHost 中的逻辑检查 frame 的当前 UIViewConroller 的视图, UINavigationControllerUINavigationController 的视图(容器)和屏幕 size ,如果它们彼此不相等, UIPeripheralHost 判定此当前情况看起来像模态窗口并设置标志 allowCustomTransition = NO . 那个关闭 UINavigationController 特定的水平动画 .

    修复 frame 的问题完全解决了我的问题 .

    如果您遇到相同的问题,可以尝试围绕这些私有方法调试内部UIKit的东西,并找到关闭水平动画的条件:

    https://github.com/JaviSoto/iOS8-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UIPeripheralHost.h

    https://github.com/JaviSoto/iOS8-Runtime-Headers/blob/master/Frameworks/UIKit.framework/_UIViewControllerKeyboardAnimationStyle.h

  • 4

    如果您不需要任何特殊内容,可以使用https://github.com/cotap/TAPKeyboardPop .

    在我的情况下,我有一些与 UIKeyboardWillShowNotificationUIKeyboardWillHideNotification 连接的逻辑在"swipe-to-back"手势上被触发 . 我把this answerTAPKeyboardPop 结合起来了,这就是我所拥有的:

    - (void)beginAppearanceTransition:(BOOL)isAppearing animated:(BOOL)animated {
        [super beginAppearanceTransition:isAppearing animated:animated];
        if (isAppearing || !animated || !_keyboardIsShown) {
            return;
        }
        if ([self respondsToSelector:@selector(transitionCoordinator)]) {
            UIView *keyboardView = self.searchBar.inputAccessoryView.superview;
            [self.searchBar becomeFirstResponder];
            [self.transitionCoordinator animateAlongsideTransitionInView:keyboardView
                                                               animation:^(id<UIViewControllerTransitionCoordinatorContext> context)
             {
                 CGRect endFrame = CGRectOffset(keyboardView.frame, CGRectGetWidth(keyboardView.frame), 0);
                 keyboardView.frame = endFrame;
             } completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
             {
                 if (![context isCancelled]) {
                     [self.searchBar resignFirstResponder];
                 }
             }];
        }
    }
    

    EDIT:

    我添加了> iOS7支持和逻辑,用于了解何时显示键盘( _keyboardIsShownUIKeyboardWillShowNotification/UIKeyboardWillHideNotificationUIKeyboardDidHideNotification/UIKeyboardDidShowNotification 中设置) .

相关问题