【发布时间】:2015-05-13 14:09:02
【问题描述】:
我有一个位于屏幕底部的UIToolbar。当用户点击工具栏中的UITextField 时,键盘出现,我检测键盘大小并通过更改其自动布局约束常量来向上移动工具栏。 (它的超级视图有一个底部间距约束。)这很好,直到用户在 iPad 上取消停靠(或拆分)键盘。此时工具栏的位置不正确。我注意到在 Messages 应用程序中,工具栏始终位于键盘上方,即使用户松开键盘也是如此,并且当用户重新定位键盘时,它始终完美地位于键盘上方。在做了一些研究之后,it was suggested 通过监听UIKeyboardWillChangeFrameNotification 并检查UIKeyboardFrameEndUserInfoKey 来处理这个问题。但是,该值可能不存在,因此我不确定在这种情况下该怎么做。
我的问题是,收听键盘框架更改通知和更新自动布局约束的正确方法是,还是有其他方法可以采取(inputAccessoryView 用于突然想到的文本字段)?如果是这样,如何检测和处理各种场景(隐藏、出现、更新框架、取消停靠、重新定位)以确保它始终精确定位在键盘上方或如果没有键盘(或有硬件键盘)在底部使用)?
请参阅下文,了解我当前如何处理 UIKeyboardWillChangeFrameNotification 处理程序(Obj-C + 伪代码的混合)中的键盘出现/消失/帧更改。
这样做的问题是它在取消停靠/拆分、取消停靠时重新定位以及使用硬件键盘时错误地定位工具栏。我还发现在键盘未停靠时展开/折叠 QuickType 不会触发 UIKeyboardWillChangeFrameNotification(停靠时会触发)。
keyboardFrameWillChange {
CGSize keyboardBeginSize = [info[UIKeyboardFrameBeginUserInfoKey] CGRectValue].size;
CGSize keyboardEndSize = [info[UIKeyboardFrameEndUserInfoKey] CGRectValue].size;
CGFloat newOffset = 0;
CGFloat toolbarPositionOffset = self.toolbarBottomConstraint.constant;
//get collection view's contentInset and contentOffset
//keyboard is appearing or disappearing or device is rotating with keyboard up
if keyboardEndSize.height == keyboardBeginSize.height {
if toolbarPositionOffset > 0 { //if dismissing
newOffset = keyboardEndSize.height;
toolbarPositionOffset -= newOffset;
//update content inset and offset
} else { //else appearing
newOffset = keyboardEndSize += newOffset;
toolbarPositionOffset += newOffset;
//update content inset and offset
}
}
//keyboard height increasing (expanding QuickType)
else if keyboardEndSize.height > keyboardBeginSize.height {
newOffset = keyboardEndSize.height - keyboardBeginSize.height;
toolbarPositionOffset += newOffset;
//update content inset and offset
}
//else keyboard height decreasing (collapsing QuickType)
else {
newOffset = keyboardBeginSize.height - keyboardEndSize.height;
toolbarPositionOffset -= newOffset;
//update content inset and offset
}
self.toolbarBottomConstraint.constant = toolbarPositionOffset;
//set new contentInset and offset
[self.toolbar layoutIfNeeded];
}
【问题讨论】:
-
只需设置
textField.inputAccessoryView=toolbar;并注释掉您编写的所有代码。 -
@iphonic 这会导致崩溃:
child view controller <UICompatibilityInputViewController> should have parent view controller <ViewController> but requested parent is <UIInputWindowController> -
它工作正常,你必须做这样的事情stackoverflow.com/a/25882277/790842,所以崩溃了。
-
@iphonic 我无法将它从超级视图中删除,它需要在键盘不可见时可见。如果我尝试将其设置为
keyboardWillShow中的inputAccessoryView,它根本不会出现。 -
是的,我明白这一点。在这种情况下,您需要收听键盘通知。