Swift3.0 4步解决键盘弹出收起时,视图跟随自动布局(XIB || SnapKit)
(写作不易,转载请注明出处)
在点击TextField键盘弹出时,会遮挡视图比如影响到输入或则是登录按钮,非常影响用户体验!
思路:
1、将要移动的视图统一放在一个View里,方便统一移动
2、保存要改变的约束(ps:我是用xib布局的,我是直接把要改变的约束拖到Controller中:bottomViewTopConstraint),如果是Snapkit布局,则定义一个属性保存即可!
3、在ViewDidLoad中注册通知中心,监听键盘弹起(UIKeyboardWillShow)、隐藏(UIKeyboardWillHide)两种状态;
3、计算要弹起的高度
4、改变约束
1 import UIKit
2
3 class WYLoginViewController: WYBaseViewController, UITextFieldDelegate {
4
5 // 使用XIB自动布局的约束
6 @IBOutlet weak var bottomViewTopConstraint: NSLayoutConstraint!
7
8 override func viewDidLoad() {
9 super.viewDidLoad()
10
11 // 注册通知中心,监听键盘弹起的状态
12 NotificationCenter.default.addObserver(self,selector: #selector(WYLoginViewController.keyboardWillChange(_:)),name: .UIKeyboardWillShow, object: nil)
13
14 // 注册通知中心,监听键盘回落的状态
15 NotificationCenter.default.addObserver(self,selector: #selector(WYLoginViewController.keyboardWillHiden(_:)),name: .UIKeyboardWillHide, object: nil)
16 }
17
18 deinit {
19
20 // 移除通知中心
21 NotificationCenter.default.removeObserver(self)
22 }
23
24 // 键盘将要显示
25 func keyboardWillChange(_ notification: Notification) {
26 if let userInfo = notification.userInfo,
27 let value = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue,
28 let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double,
29 let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? UInt {
30
31 // 获取键盘的高度
32 let frame = value.cgRectValue
33 let intersection = frame.intersection(self.view.frame)
34 // 计算指定视图的底部坐标Y到ViewController‘Bottom的高度
35 let sureButtonBottomOriginY = 64.0 + sureButton.frame.origin.y + sureButton.frame.size.height
36
37 // 计算差值,即要移动的值
38 let dValue = CGFloat(intersection.height - self.view.frame.size.height + sureButtonBottomOriginY)
39
40 // 赋值给约束 = 原始值 - 差值
41 bottomViewTopConstraint.constant = 64 - dValue
42
43 // 刷新约束
44 UIView.animate(withDuration: duration, delay: 0.0,options: UIViewAnimationOptions(rawValue: curve), animations: { _ in
45
46 self.view.layoutIfNeeded()
47
48 }, completion: nil)
49
50 }
51 }
52
53 // 键盘将要隐藏
54 func keyboardWillHiden(_ notification: Notification) {
55 if let userInfo = notification.userInfo,
56 let value = userInfo[UIKeyboardFrameEndUserInfoKey] as? NSValue,
57 let duration = userInfo[UIKeyboardAnimationDurationUserInfoKey] as? Double,
58 let curve = userInfo[UIKeyboardAnimationCurveUserInfoKey] as? UInt {
59
60 let frame = value.cgRectValue
61 let intersection = frame.intersection(self.view.frame)
62
63 // 如果键盘的高度 == 0, 约束的值直接等于原来的值
64 if intersection.height == 0 {
65
66 bottomViewTopConstraint.constant = 64
67
68 } else {
69
70 }
71
72 // 刷新视图
73 UIView.animate(withDuration: duration, delay: 0.0,options: UIViewAnimationOptions(rawValue: curve), animations: { _ in
74
75 self.view.layoutIfNeeded()
76
77 }, completion: nil)
78
79 }
80 }
81
82 // 点击空白处注销第一响应,键盘回落
83 override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
84
85 view.endEditing(true)
86 }
87
88 // TextFieldDelegate 点击Return按钮注销第一响应,键盘回落
89 func textFieldShouldReturn(_ textField: UITextField) -> Bool {
90
91 textField.resignFirstResponder()
92
93 return true
94 }
95
96 }