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 }
