在 textField 成为第一响应者时获取外部/虚拟键盘的事件

Posted

技术标签:

【中文标题】在 textField 成为第一响应者时获取外部/虚拟键盘的事件【英文标题】:Get event for external/virtual keyboard while textField become first responder 【发布时间】:2013-09-09 06:53:09 【问题描述】:

在我的 iPad 应用程序中,我使用表单样式呈现控制器

controller.modalPresentationStyle=UIModalPresentationFormSheet;

在横向模式下,当设备的键盘打开时,我会设置 tableView 的大小,以便用户可以看到 table 的所有记录。

获取显示/隐藏键盘事件。我已经设置NSNotification

问题

但是当用户使用外部/虚拟键盘在表格单元格的文本字段中点击时,我没有收到键盘显示/隐藏事件。 因此,当 textfield 成为第一响应者时,Tableview 的大小会减小,但用户连接外部键盘时则不需要。

任何人都可以在这里指导/帮助,我该怎么办?这样我就可以在使用外部键盘时停止设置大小。

注册键盘事件

- (void)registerForKeyboardNotifications

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWasShown:)
                                             name:UIKeyboardDidShowNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(keyboardWasHidden:)
                                             name:UIKeyboardDidHideNotification object:nil];


在自动旋转和文本字段成为第一响应者时设置框架

-(void)setFramesOfTable


CGRect rct=tableView.frame;
if(appDel.isThisIPad && ([[UIApplication sharedApplication] statusBarOrientation]==UIInterfaceOrientationLandscapeLeft || [[UIApplication sharedApplication] statusBarOrientation]==UIInterfaceOrientationLandscapeRight) && [selectedField isFirstResponder])

    rct.size.height=400.0;

else

    rct.size.height=576.0;

tableView.frame=rct;


- (void)textFieldDidBeginEditing:(UITextField *)textField

selectedField = textField;
[self setFramesOfTable];


-(NSUInteger)supportedInterfaceOrientations

[self setFramesOfTable];
return UIInterfaceOrientationMaskAll;

谢谢。

【问题讨论】:

@IronManGill 刚刚编辑了代码,但我认为现有代码无济于事,因为只有键盘事件可以解决问题。但在使用外接键盘时不触发。 【参考方案1】:

在文本字段开始编辑时更改表格的框架不是一个好主意。在 iPad 上,用户可以使用外接键盘、对接键盘或拆分键盘。

如果用户有外接键盘,则无需调整窗口大小。使用外接键盘时不会出现屏幕键盘,因此无需调整窗口大小。

如果用户使用的是分体式键盘,您实际上不必担心调整窗口大小。如果他们拆分键盘,他们可以将键盘放在 UI 的中间,这使得重新排列您的 UI 成为不可能(或至少不切实际),因此它至少不会被拆分键盘的一小部分覆盖。如果用户拆分了键盘并掩盖了重要的 UI 组件,则需要将键盘移开。

调整 UI 大小的最佳方法是在键盘中使用 ChangeFrame/Hide 方法

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillChangeFrame:) name:UIKeyboardWillChangeFrameNotification object:nil];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

在这些事件的处理程序中,您可以获得键盘高度,并相应地调整 UI

-(void)keyboardWillChangeFrame:(NSNotification*)notification

    NSDictionary* info = [notification userInfo];
    NSValue* kbFrame = info[UIKeyboardFrameEndUserInfoKey];
    NSTimeInterval animationDuration = [info[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
    CGRect keyboardFrame = [kbFrame CGRectValue];
    BOOL isPortrait = UIDeviceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation);
    CGFloat height = isPortrait ? keyboardFrame.size.height : keyboardFrame.size.width;

这将为您获取 animationDuration 和键盘的高度,以便您可以使用 UIView animateWithDuration 块为您的 tableview 的帧更改设置动画,使其不会被键盘遮挡。

在keyboardWillHide中:你只需要从NSNotification获取animationDuration(方法同上)(高度明显为0)。然后使用另一个 UIView animateWithDuration 块将您的 tableview 调整为原始大小

【讨论】:

是的。完美只需要使用 UIKeyboardWillChangeFrameNotification。从那里我可以获得键盘高度。但是从上面的代码中,我无法正确地转换它。像 CGRect keyboardFrame = [[info objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue]; CGRect ownFrame = [appDel.window convertRect:self.view.frame fromView:self.view.superview]; CGRectcoveredFrame = CGRectIntersection(ownFrame, keyboardFrame); CoveredFrame = [appDel.window convertRect:coveredFrame toView:self.view.superview]; 我不确定我是否完全理解您的问题。我不知道你需要有盖框架做什么。一旦你有了键盘的高度,你可能只需将视图/超级视图的框架调整为(原始高度)-(键盘高度)。

以上是关于在 textField 成为第一响应者时获取外部/虚拟键盘的事件的主要内容,如果未能解决你的问题,请参考以下文章

iOS:UIAlertController 上的 textField 成为当前警报时的第一响应者

带有 TextField 和第一响应者的自定义 UITableViewCell

Mac - 让文本框成为第一响应者

TextField 中的 IOS8 文本在焦点上反弹

ObjC iOS11:在 inputAccessoryView 中成为第一响应者时,TextField 不显示

如何获取已请求成为第一响应者的 UIView?