UITextView自適應+鍵盤切換

效果圖

textView1.gif

主要解決2個問題:

  • 鍵盤切換的之后textView父視圖frame的改變問題
  • 輸入文字時textView高度的變化和父視圖frame的變化

切換鍵盤

這里切換鍵盤用到的是textView的inputView屬性,如果不給注銷和出現的方法加動畫,鍵盤改變的回調給父視圖的frame會改變兩次,出現動畫亂跳的問題,這里只能強行解決了一下

    // 切換表情按鈕點擊
    @objc fileprivate func changeButtonDidClick(_ button: UIButton) {
        changeButton.isSelected = !button.isSelected
        UIView.animate(withDuration: 0.01) { 
            self.textView.resignFirstResponder()
            self.textView.inputView = self.textView.inputView == nil ? self.emojiView : nil
            self.textView.becomeFirstResponder()
        }
    }

監聽鍵盤的出現和消失

// 這里監聽鍵盤的2個方法,其實可以監聽鍵盤frameWillChange
// 鍵盤將要出現
    @objc fileprivate func keyboardWillShowNotification(notification: Notification) {
        print(notification.userInfo!["UIKeyboardFrameEndUserInfoKey"] ?? false)
        let changeFrame = notification.userInfo!["UIKeyboardFrameEndUserInfoKey"] as! CGRect
        let changeHeight = changeFrame.size.height
        keyboardWillShowCallBack?(changeHeight)
    }
    
    // 鍵盤將要消失
    @objc fileprivate func keyboardWillHideNotification(notification: Notification) {
        print(notification.userInfo!["UIKeyboardFrameEndUserInfoKey"] ?? false)
        let changeFrame = notification.userInfo!["UIKeyboardFrameEndUserInfoKey"] as! CGRect
        let changeHeight = changeFrame.size.height
        keyboardWillHideCallBack?(changeHeight)
    }

鍵盤回調方法

        var inputViewHeight: CGFloat = 50 // 記錄textView的高度
        var inputViewY: CGFloat = appHeight - inputViewHeight // 記錄textView的Y
        var letInputViewY: CGFloat = inputViewY
        
        let inputView = InputView(frame: CGRect(x: 0, y: inputViewY, width: appWidth, height: inputViewHeight))
        
// 鍵盤將要出現
        inputView.keyboardWillShowCallBack = { keyboardHeight in
            inputViewY = appHeight - keyboardHeight - inputViewHeight
            letInputViewY = appHeight - keyboardHeight
            inputView.frame = CGRect(x: 0, y: inputViewY, width: appWidth, height: inputViewHeight)
        }
// 鍵盤將要消失
        inputView.keyboardWillHideCallBack = { keyboardHeight in
            inputViewY = appHeight - inputViewHeight
            letInputViewY = appHeight
            inputView.frame = CGRect(x: 0, y: inputViewY, width: appWidth, height: inputViewHeight)
        }
// textView高度改變回調
        inputView.textViewHeightChanged = { changeHeight in
            inputViewHeight = changeHeight + 10
            inputView.frame = CGRect(x: 0, y: letInputViewY - inputViewHeight, width: appWidth, height: changeHeight + 10)
        }

letInputViewY 是為了記錄當鍵盤切換時Y的改變量,當textView行高發生變化的時候計算偏移的Y
inputViewHeight 是為了記錄textView改變的高度,當切換鍵盤時計算偏移的Y

解決textView自適應問題

核心代碼還是利用textView.sizeThatFits方法計算textView的新高度然后重新賦值,并回調給父視圖改變父視圖的Y即可,這里改變了一下textView的attributes屬性來調整行間距,當發送emoji表情的時候會導致emoji的高度高于計算的大小,emoji的下半邊會被遮蓋,demo沒有實現表情鍵盤

func textViewDidChange(_ textView: UITextView) {
        
        let maxHeight: CGFloat = 90.0;
        let width = textView.frame.size.width;
        let newSize = textView.sizeThatFits(CGSize(width: width, height: CGFloat(MAXFLOAT)))
        let textHeight = CGFloat(newSize.height)
        
        // 修改TextView的行距和attributes
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = 5
        let attributes = [NSAttributedStringKey.font: UIFont.systemFont(ofSize: 15), NSAttributedStringKey.paragraphStyle: paragraphStyle]
        textView.attributedText = NSAttributedString(string: textView.text, attributes: attributes)
        
        if textHeight <= maxHeight {
            textView.isScrollEnabled = false
            textView.bounds.size.height = textHeight >= 40 ? textHeight : 40 // 高度大于40的時候再高邊textView高度
            textViewHeightChanged?(textView.bounds.size.height)
        }else
        {
            textView.isScrollEnabled = true
            textView.bounds.size.height = maxHeight
            textViewHeightChanged?(textView.bounds.size.height)
        }
    }

主要為了寫個demo練習一下swift,并且養成寫簡書的習慣,剛就業不到半年的小白,借助簡書記錄自己的學習之路,代碼質量不是很高??
demo:https://github.com/qq421680227/textViewSizeFit

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

推薦閱讀更多精彩內容

  • 發現 關注 消息 iOS 第三方庫、插件、知名博客總結 作者大灰狼的小綿羊哥哥關注 2017.06.26 09:4...
    肇東周閱讀 12,251評論 4 61
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,467評論 25 708
  • 磨蹭一個月,終于把《越獄》四季看完了。每次總是會提前看底下的評論,知道一點后面的劇情,這是一部沒法讓人快...
    小雨正在奔跑9299閱讀 5,269評論 0 0
  • 熱播劇《那年花開月正圓》即將接近尾聲。該劇以陜西省涇陽縣安吳堡吳氏家族的史實為背景,講述了清末出身民間的陜西女首富...
    杜小美閱讀 2,045評論 0 0
  • 日前讀報,一個年僅二十幾的女子因男友另結新歡,承受不了情感重創,用幾片斷腸草葉子結束生命,經搶救無效身亡,留下年邁...
    悠悠心旅閱讀 311評論 0 0