使用UIView同步animation键盘,同时在iOS7中向后滑动

我想在iOS7中获得类似于Messages应用程序的行为(在大多数短信应用程序中也是常见的),在对话视图中从屏幕左边缘向右滑动的行为将类似于UINavigationController中的后退button。

我已经设法实现这种行为,但是,如果在呈现视图中打开键盘,当我开始向后滑动时,键盘会卡住,并且在我移动手指时不会右移视图。 我想将键盘和呈现视图制作为一个单元,而不是将键盘放置在其他视图之上,并且在后面制作animation,这就是我现在得到的(参见第二个截图):

更新:请注意,主视图animation完成后,键盘将最终消失;我所关注的是滑动过程中键盘的位置,并且当您不断触摸设备的一半时与实际视图同步,第二个屏幕截图阐明了这个需要的行为,我也想知道为什么它不是默认的。)

只需在Xcode 5.0.2中创build一个新的主 – 细节iPhone应用程序,并在StoryBoard的详细视图(最好是上半部分的某处)中添加一个文本字段,运行该应用程序,添加一个项目点击它可以进入详细视图并点击你添加的文本框。 从设备的左侧边缘轻扫,同时保持你的手指,你会看到这个问题。

期望的行为:

期望的行为

目前的行为:

键盘撕裂

不幸的是,没有内置的方法来做到这一点。 我真的希望有像UIScrollViewKeyboardDismissModeInteractiveUIViewController的东西。

现在,要做viewControllers之间的任何animation,你应该使用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 – 你可以通过创build一个假inputAccessoryView来获得:

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

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

它应该只是自动工作,但有时候并不是因为某些条件。

如果当前的firstResponder位于活动UIViewController内部,并且在整个UINavigationController机制中closures,则预期的键盘animation(水平)将自动执行。 因此,有时这种默认行为被其他奇怪的因素打破,键盘开始消失,而不是滑动animation而不是水平animation。

我花了一些时间debugging内部UIKit的东西(围绕方法needDeferredTransitionallowCustomTransition和其他)来find一个特殊的因素,在我的情况下发挥关键作用。

我发现UIPeripheralHost里面的逻辑检查当前UIViewConroller视图的frameUINavigationController的视图(容器)的frame和屏幕size ,如果不相等, UIPeripheralHost判定这个现在的情况看起来像模态窗口并设置标志allowCustomTransition = NO 。 即closuresUINavigationController – 特定的水平animation。

解决frame问题完全解决了我的问题。

如果您遇到同样的问题,您可以尝试debugging这些私有方法的内部UIKit东西,并findclosures水平animation的条件:

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

如果你不需要任何特殊的东西,你可以使用https://github.com/cotap/TAPKeyboardPop

在我的情况下,我已经有一些逻辑与UIKeyboardWillShowNotificationUIKeyboardWillHideNotification连接,这些逻辑是通过“滑动到背部”手势触发的。 我已经结合这个答案和TAPKeyboardPop ,这是我得到的:

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

编辑:

我已经添加了> iOS7的支持和逻辑知道什么时候显示键盘( _keyboardIsShown设置在UIKeyboardWillShowNotification/UIKeyboardWillHideNotificationUIKeyboardDidHideNotification/UIKeyboardDidShowNotification )。