隨筆:使用SnapKit的updateConstraint方法無法更新storyboard中建立的約束問題

今天我在做自適應高度的UITextView時,無意中碰到了一個非常奇怪的問題:

我使用純代碼佈局+snapKit建立約束的時候,在代理方法裏面使用代碼:

    func textViewDidChange(_ textView: UITextView) {
        let frame = textView.frame
        let constraintSize = CGSize(width: frame.width, height: CGFloat(MAXFLOAT))
        let size = textView.sizeThatFits(constraintSize)
        if size.height <= maxRowHeight {
            textView.snap.updateConstraint({
                $0.height.equalToSuperView().offset(size.height).priority(999)
            })
            NotificationCenter.default.post(name: IBTextView.RowChangeNotification, object: nil)
        }
    }

這時沒有任何問題。文本框可以自動換行!!!

However

當我使用snapKit+storyboard開發時想要使用同樣的代碼更新從storyboard中建立的約束時,就沒有效果了。後面通過檢查,發現snapKit框架自身有把系統約束給封裝一層:

public class LayoutConstraint : NSLayoutConstraint {

這個就導致了snapKit在執行自己的updateConstraint方法時由於不認識NSLayoutConstraint,直接把原生的約束給忽略了......

這裏我就是想diss它一下,看!你的bug😁

最後

給出我想到的解決辦法:

    func textViewDidChange(_ textView: UITextView) {
        let frame = textView.frame
        let constraintSize = CGSize(width: frame.width, height: CGFloat(MAXFLOAT))
        let size = textView.sizeThatFits(constraintSize)
        if size.height <= maxRowHeight {
            let constraints = textView.constraints.filter({ $0.firstAttribute == NSLayoutConstraint.Attribute.height })
            if constraints.count > 0 {
                textView.removeConstraints(constraints)
            }
            let newConstraints = NSLayoutConstraint(item: textView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: size.height)
            newConstraints.priority = UILayoutPriority(rawValue: 999)
            textView.addConstraint(newConstraints)
            
            NotificationCenter.default.post(name: IBTextView.RowChangeNotification, object: nil)
        }
    }

還有一個疑惑🤔

我這裏使用filter是被逼無奈啊!!!本來我可以只用一個first查詢就可以了的,但是我發現蘋果輸入法的鍵盤在點擊提示中文信息的時候這個textViewDidChange方法被執行了兩次。點鍵盤上面的字母是正常調用一次的😢。難道是因爲一箇中文字符所佔字節位數更長?所以才?煩請知道緣由的看客老爺在評論區給出答案,我們討論一下。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章