Swift 解決鍵盤遮蓋問題封裝

日常開發中,經常會遇到輸入框被鍵盤遮蓋的問題, 本次思路是 將鍵盤處理相關代碼封裝成一個 單利的工具類, 通過監聽系統的鍵盤相關通知來 獲取鍵盤信息,實現被遮蓋視圖的上移操作,上代碼:

import Foundation
class KeyBoderHandleTool: NSObject {
    
    //可能會被遮蓋的 view
    private var keyBoderHandleView :UIView?
    
    //可能會被遮蓋的view 的遮蓋高度
    private var keyBoderHandleHeigt :CGFloat = 0.0
    private let disposeBag = DisposeBag()
    
    //單利對象
    private static var sharedTool :KeyBoderHandleTool?
    
    //獲取單利對象
    class func getSharedKeyBoderTool() ->KeyBoderHandleTool{
        
        guard let instance = sharedTool else {
            sharedTool = KeyBoderHandleTool()
            return sharedTool!
        }
        return instance
    }
    
    
    //銷毀單利對象
    class func destroy() {
        sharedTool = nil
    }

    // 私有化init 初始方法
    private override init() {}
    
    
    //監聽鍵盤彈出
    /// 處理鍵盤 遮蓋問題
    ///
    /// - Parameters:
    ///   - handleView: 需要處理的視圖
    ///   - offsetY: 如果是 可滑動的view  就傳入 y 軸上的偏移量
    func handleKeyBoderAction(handleView :UIView, offsetY :CGFloat?){
        
        if keyBoderHandleView != nil {
            //更換遮蓋view
            self.keyBoderHandleView = handleView
            return
        }
        
        print("開始了****************")
        self.keyBoderHandleView = handleView
        
        //監聽鍵盤出現
        weak var weakSelf = self
        NotificationCenter.default.addObserver(forName: UIResponder.keyboardDidShowNotification, object: nil, queue: OperationQueue.main) { (notification) in
            
            let info = notification.userInfo
            
            //鍵盤動畫時間
            let duration = (info?[UIResponder.keyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
            
            //鍵盤坐標尺寸
            let keyBoderRect = (info?[UIResponder.keyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
            //獲取鍵盤被遮蓋部分的高度
            let keyBoderHeight = keyBoderRect.size.height      //獲取鍵盤高度
            let boundHeight = UIScreen.main.bounds.size.height  //屏幕高度
            
            let viewMaxY :CGFloat = offsetY == nil ? weakSelf!.keyBoderHandleView!.frame.maxY : (weakSelf!.keyBoderHandleView!.frame.maxY-offsetY!)
            //需要處理的 view 的絕對 Y 坐標
            
            //計算出被遮蓋部分的高度
            weakSelf!.keyBoderHandleHeigt = viewMaxY - (boundHeight-keyBoderHeight)
            if weakSelf!.keyBoderHandleHeigt <= 0 {
                return
            }
            
            //將其父視圖 上移被遮蓋的高度
            if let superView = weakSelf!.keyBoderHandleView!.superview {
                
                UIView.animate(withDuration: duration, animations: {
                    weakSelf!.keyBoderHandleView!.superview!.frame = CGRect.init(x: superView.frame.origin.x, y: superView.frame.origin.y - weakSelf!.keyBoderHandleHeigt, width: superView.bounds.size.width, height: superView.bounds.size.height)
                    
                })
                
            }
            print("打印數據--消失--\(weakSelf!.keyBoderHandleHeigt)----\(weakSelf!.keyBoderHandleView!.tag)")
            
        }
        
        NotificationCenter.default.addObserver(forName: UIResponder.keyboardWillHideNotification, object: nil, queue: OperationQueue.main) { (notification) in
            
            let info = notification.userInfo
            if weakSelf!.keyBoderHandleHeigt <= 0{
                return
            }
            
            //鍵盤動畫時間
            let duration = (info?[UIResponder.keyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
            
            //將高度還原
            if let superView = weakSelf!.keyBoderHandleView!.superview {
                UIView.animate(withDuration: duration, animations: {
                    weakSelf!.keyBoderHandleView!.superview!.frame = CGRect.init(x: superView.frame.origin.x, y: superView.frame.origin.y + weakSelf!.keyBoderHandleHeigt, width: superView.bounds.size.width, height: superView.bounds.size.height)
                    
                })
            }
            
            print("打印數據--消失--\(weakSelf!.keyBoderHandleHeigt)----\(weakSelf!.keyBoderHandleView!.tag)")
            
        }
    }

    deinit {
        
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardWillHideNotification, object: nil)
        NotificationCenter.default.removeObserver(self, name: UIResponder.keyboardDidShowNotification, object: nil)
    }
}

使用時, 只需要直接調用:

KeyBoderHandleTool.getSharedKeyBoderTool().handleKeyBoderAction(handleView: textField, offsetY: nil)

當輸入框在 可滑動控件上時,記得傳入 y 軸上的 offset,否則傳nil

注意點:

1:在 確定不需要再監聽的情況下可以 調用 工具類中的 銷毀方法
2: 發生界面跳轉等情況時,請先將鍵盤隱藏(self.view.endEditing(true))

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容