iOS开发,键盘弹出问题总结
在APP开发中,我们总是会使用到文字输入控件,其中最常用的就是系统控件UITextField及UITextView。
输入控件接收到触摸事件,或是我们通过代码调用becomeFirstResponder
方法,都将呼出键盘,以满足用户输入必要信息的需要。
在键盘弹出之后,我们总会遇到一些预料之中或预料之外的问题,这些问题或许无伤大雅,但总归是会让我们的用户感受到那么一丝丝的不友好。
毫无疑问,关于键盘的弹出与消失从来都不是什么棘手的问题,我们总是能找到十分简单的方法,轻易的解决这些现象。然而,在解决这些问题时,我们采用的代码可能并没有想象中的那么简洁,或者说我们在设计上采用的方法并不那么合理高效。
以下问题是键人自己在工作中遇到过,解决方案则是通过自己摸索并结合一些网友的设计方案,自行总结使用的。
同时,在下也十分欢迎各位朋友提出新的解决方案,实现更简洁的代码+更高效的设计+更智能的服务+更傻瓜的应用。
闲话少说,言归正传,接下来就让我们探讨一下关于键盘弹出与消失的一些问题。
问题1. 键盘弹出后遮盖输入框

我输入的是个啥??这个问题大概是工作中最常见到的现象,也是导致一些新手开发者狂躁搔首,以致不得不拿着大把辛苦挣来的毛爷爷,忍着心痛把他们交到嘴巴都笑歪的美发师手中的罪魁祸首。接下来,就让我们分析一下这个问题的给我们造成的困扰和解决的方式。
- 经过查阅资料,我们发现了这么两个通知
UIApplication.keyboardWillShowNotification
和UIApplication.keyboardDidShowNotification
,根据字面意思,我们可以知道,这两个通知都是伴随键盘弹出而发出的,第一个为将要显示,第二个为键盘已经显示到位。嗯,监听这两个通知,在键盘将要出现的时候把输入框调高到键盘上方。
IMG_1941.GIF
private let userNameTF:UITextField = {
let textField = UITextField(frame: .zero)
textField.backgroundColor = UIColor.lightGray
textField.layer.borderWidth = 1
textField.layer.borderColor = UIColor.red.cgColor
textField.placeholder = "请输入用户名"
return textField
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
view.addSubview(userNameTF)
NotificationCenter.default.addObserver(
self, selector: #selector(keyBoardWillShow(_:)),
name: UIApplication.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(
self, selector: #selector(keyBoardDidShow(_:)),
name: UIApplication.keyboardDidShowNotification, object: nil)
}
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
userNameTF.frame = CGRect(x: 50,
y: self.view.bounds.height-100,
width: self.view.bounds.width-100, height: 50)
}
@objc func keyBoardWillShow(_ noti:Notification) {
userNameTF.frame = CGRect(x: 50,
y: self.view.bounds.height-400,
width: self.view.bounds.width-100, height: 50)
}
@objc func keyBoardDidShow(_ noti:Notification) {
userNameTF.frame = CGRect(x: 50,
y: self.view.bounds.height-400,
width: self.view.bounds.width-100, height: 50)
}
美滋滋,遮盖文字的问题就这么愉快的解决了。
但是,如果我就这么关上电脑,哼着小曲去炸个肉丸,榨杯豆浆的话,你此时一定会对着屏幕吐上一口祖传三十年的老T。
毕竟,app中的键盘和电脑外设键盘不同,我在完成以上的文字后,自然可以关上电脑,倒上一杯热水,如果心情足够愉悦,可能还会找出一块抹布擦一擦键盘。
app中键盘在使用完毕后却不能不管不顾,我们要秉承国际通用规则,谁开发谁保护,谁污染谁治理。我们在app中使用了键盘,对界面造成一定程度的污染,那么使用完毕后就必须将键盘回收,将被污染界面的界面复原。
问题2. 键盘消失问题
键盘的消失,从来都不是什么特别难以处理的事情。当我们还只是一个粉嫩的新手开发者时,我们就已经知道每一个继承自UIResponder
的控件都有这么一个方法resignFirstResponder
,与之相对的则是becomeFirstResponder
。
当我们使用了控件UITextField
或UITextView
,只需要轻轻点击一下,键盘就从手机底部弹了出来,让我们愉快的输入账号、密码、心情、天气等任何我们想要表达的内容。当我们输入完毕以后,只需要让输入框UITextField
或UITextView
调用一下resignFirstResponder
,键盘就会重新返回手机底部并消失。
所以,我们唯一需要关心的问题,就是用户在什么时候输入完毕。通畅状况下,我们会为输入框控件设置returnKeyType
为UIReturnKeyType.next
或UIReturnKeyType.done
。此时,我们就可以通过代理用户点击return
按钮的事件,来断定用户已经输入完毕了。即,我们重写了控件的代理方法textFieldShouldReturn
,在响应时为为输入框调用resignFirstResponder
即可将正在输入的键盘召唤回家。
private let userNameTF:UITextField = {
let textField = UITextField(frame: .zero)
textField.returnKeyType = .done
textField.backgroundColor = UIColor.lightGray
textField.layer.borderWidth = 1
textField.layer.borderColor = UIColor.red.cgColor
textField.placeholder = "请输入用户名"
return textField
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.white
view.addSubview(userNameTF)
userNameTF.delegate = self
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardWillShow(_:)), name: UIApplication.keyboardWillShowNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(keyBoardDidShow(_:)), name: UIApplication.keyboardDidShowNotification, object: nil)
}
extension ViewController:UITextFieldDelegate {
func textFieldShouldReturn(_ textField: UITextField) -> Bool {
textField.resignFirstResponder()
return true
}
}
完美,键盘弹出输入文字,输入完毕回收键盘,一点儿毛病都没有。
等等,发生了什么,为什么输入框待在这么高的地方不走了?
显然,这个输入框并不是一个成熟的输入框,它不会在键盘消失的时候回到属于自己的位置去。
但是,作为一个成熟的萌新开发者,我们当然不允许在自己开发的app众存在这么一个近乎弱智的现象。