当键盘被调用时,我正在将UIView向上移动,在模拟器中可以正常工作,但是无论出于什么原因,我两次在UIKeyboardWillShow通知中调用实际代码时,我都会在实际设备上运行代码。我没有使用任何自定义键盘。
在viewDidLoad方法中,我称为此方法。
func registerKeyBoardNotifications(){
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillAppear(notification:)), name: .UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillBeHidden(notification:)), name: .UIKeyboardWillHide, object: nil)
}
然后在viewWillDisappear中删除这些观察者。
@objc func keyBoardWillAppear(notification: NSNotification){
if let userInfo = notification.userInfo,
let endFrame = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue,
let beginFrame = userInfo[UIKeyboardFrameBeginUserInfoKey] as? NSValue,
beginFrame.isEqual(to: endFrame) == false{
let keyboardSize = endFrame.cgRectValue
self.view.frame.origin.y -= keyboardSize.height - keyboardConstant
signUpButton.isEnabled = false
}
}
keyboardWillAppear处理程序在物理设备上被调用两次,但在模拟器中被调用一次,在最近的两天里试图弄清楚这一点。
Xcode 9.4.1迅捷4.1
答案 0 :(得分:1)
这可能发生,并且没有任何文档可以保证仅一个通知。
因此,您应该只在代码中处理它,而不每次都减去键盘高度。一个更聪明的解决方案是根据键盘的末端框架来计算您的视框。
答案 1 :(得分:0)
正确的方法是,问自己正确的问题。例如,以前是不是键盘没有覆盖我的视野,现在是?那是应该被视为“进入”的场合。
我有一个实用程序功能,可根据通知的userInfo
字典和我们关注的视图范围来计算几何形状。如果键盘不在视图的范围之内,而现在已经在视图的范围之内,则说明它正在进入;如果它在视图的范围之内,但现在不在范围之内,则它正在退出。我们返回该信息,以及视图边界坐标中的键盘框架:
enum KeyboardState {
case unknown
case entering
case exiting
}
func keyboardState(for d:[AnyHashable:Any], in v:UIView?)
-> (KeyboardState, CGRect?) {
var rold = d[UIResponder.keyboardFrameBeginUserInfoKey] as! CGRect
var rnew = d[UIResponder.keyboardFrameEndUserInfoKey] as! CGRect
var ks : KeyboardState = .unknown
var newRect : CGRect? = nil
if let v = v {
let co = UIScreen.main.coordinateSpace
rold = co.convert(rold, to:v)
rnew = co.convert(rnew, to:v)
newRect = rnew
if !rold.intersects(v.bounds) && rnew.intersects(v.bounds) {
ks = .entering
}
if rold.intersects(v.bounds) && !rnew.intersects(v.bounds) {
ks = .exiting
}
}
return (ks, newRect)
}
当键盘显示时,我们检查它是否正在输入,并做出相应的响应:
@objc func keyboardShow(_ n:Notification) {
let d = n.userInfo!
let (state, rnew) = keyboardState(for:d, in:myView)
if state == .entering {
// ...
}
}
答案 2 :(得分:0)
我似乎已经弄清楚了为什么UIkeyboardWillShow Notification通知在物理设备而不是模拟器上触发两次。设置某些“文本输入”特征时,它与键盘上方的键盘建议有关。任何在键盘上方引起建议的文本输入特征都会导致该通知触发两次,而不是一次,我猜测是一次针对键盘本身,另一次针对键盘上方的建议栏。 (在我的情况下,因为在模拟器上没有建议,所以它在模拟器中触发了一次,但在设备上触发了两次,因为在真实设备上有建议)。这是一个奇怪的案例,似乎没有记录在案。
一种解决方法(我选择的途径)是通过将所有“文本输入”特征设置为默认值并将文本字段的内容类型设置为“用户名”来禁用所有建议。
另一种解决方案是在调整您尝试移动的UIView的框架之前,先考虑代码中的第二个UIkeyboardWillShowNotifcation通知。