iMessage风格在iOS应用程序中退出键盘

我一直在想,是否有可能在消息应用程序中复制Apple iOS5键盘的行为,而不使用任何私人API调用。 当您向下滚动消息应用程序中的键盘时,键盘将崩溃,留下更多空间来查看消息 – 尝试查看。

我无法find任何指向这一点,而不必开始跳过一些严重的箍来获得键盘视图的实例。 而且我很确定苹果公司对此不会感到满意。

除了下面给出的答案,你可以看到我的实现在这里完全烘焙的xcode项目: https : //github.com/orta/iMessage-Style-Receding-Keyboard

这是一个不完整的解决scheme,但它应该给你一个很好的起点。

将下面的ivars添加到你的UIViewController中:

CGRect keyboardSuperFrame; // frame of keyboard when initially displayed UIView * keyboardSuperView; // reference to keyboard view 

将一个inputAccessoryView添加到您的文本控制器。 我创build了一个小视图来插入作为accessoryView:

 accView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)]; accView.backgroundColor = [UIColor clearColor]; textField.inputAccessoryView = accView; 

我将上面的代码添加到-(void)loadView

注册以在加载视图时接收UIKeyboardDidShowNotification和UIKeyboardDidHideNotification:

 - (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil]; return; } 

添加指定为通知select器的方法:

 // method is called whenever the keyboard is about to be displayed - (void)keyboardWillShow:(NSNotification *)notification { // makes keyboard view visible incase it was hidden keyboardSuperView.hidden = NO; return; } // method is called whenever the keyboard is displayed - (void) keyboardDidShow:(NSNotification *)note { // save reference to keyboard so we can easily determine // if it is currently displayed keyboardSuperView = textField.inputAccessoryView.superview; // save current frame of keyboard so we can reference the original position later keyboardSuperFrame = textField.inputAccessoryView.superview.frame; return; } 

添加方法来跟踪触摸并更新键盘视图:

 // stops tracking touches to divider - (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { CGRect newFrame; CGRect bounds = [[UIScreen mainScreen] bounds]; newFrame = keyboardSuperFrame; newFrame.origin.y = bounds.size.height; if ((keyboardSuperView.superview)) if (keyboardSuperFrame.origin.y != keyboardSuperView.frame.origin.y) [UIView animateWithDuration:0.2 animations:^{keyboardSuperView.frame = newFrame;} completion:^(BOOL finished){ keyboardSuperView.hidden = YES; keyboardSuperView.frame = keyboardSuperFrame; [textField resignFirstResponder]; }]; return; } // updates divider view position based upon movement of touches - (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch * touch; CGPoint point; CGFloat updateY; if ((touch = [touches anyObject])) { point = [touch locationInView:self.view]; if ((keyboardSuperView.superview)) { updateY = keyboardSuperView.frame.origin.y; if (point.y < keyboardSuperFrame.origin.y) return; if ((point.y > updateY) || (point.y < updateY)) updateY = point.y; if (keyboardSuperView.frame.origin.y != updateY) keyboardSuperView.frame = CGRectMake(keyboardSuperFrame.origin.x, point.y, keyboardSuperFrame.size.width, keyboardSuperFrame.size.height); }; }; return; } 

免责声明:

  • 按照第一个响应辞职时,键盘移回到其原始位置,然后滑下屏幕。 要使键盘更加stream畅,首先需要创build一个animation,将键盘从屏幕上移开,然后隐藏视图。 我将这部分作为练习留给读者。
  • 我只在iOS 5模拟器和iOS 5的iPhone上进行了testing。我还没有使用早期版本的iOS进行testing。

我为了testing这个概念而创build的SlidingKeyboard项目可以从BindleKit的examples目录的GitHub中获得:

https://github.com/bindle/BindleKit

编辑:更新示例来解决第一个免责声明。

在iOS 7中,UIScrollView上有一个keyboardDismissMode属性。 所以只要将它设置为“UIScrollViewKeyboardDismissModeInteractive”,你会得到这种行为。 在UIScrollView子类(如UITableView)中工作。

 self.tableView.keyboardDismissMode = UIScrollViewKeyboardDismissModeInteractive; 

Swift 3:

 tableView.keyboardDismissMode = .interactive 

或者在你的UIScrollView子类的属性检查器中更改故事板(如果使用的话)。

弗拉基米尔简单的解决scheme将隐藏键盘,因为用户向下滚动。 但是,为了完成关于iMessage的问题,为了使TextField始终可见并且锚定在键盘的顶部,您需要实现以下方法:

 - (UIView *) inputAccessoryView { // Return your textfield, buttons, etc } - (BOOL) canBecomeFirstResponder { return YES; } 

这是一个很好的教程 ,更多的分解