Swift-通過SnapKit實(shí)現(xiàn)更新約束動(dòng)畫

筆記風(fēng)格借鑒Knight_SJ

需求點(diǎn):

通過觸發(fā)鍵盤實(shí)現(xiàn)更新視圖約束的動(dòng)畫效果,網(wǎng)上有很多通過Masonry實(shí)現(xiàn)動(dòng)畫更新約束的教程西疤,本人用Swift簡單實(shí)現(xiàn)了下。
效果如下:

效果圖.gif

特點(diǎn):
獲取鍵盤彈出和回收時(shí)間,實(shí)時(shí)更新約束拉宗,實(shí)現(xiàn)彈出或回收鍵盤與更新約束動(dòng)畫時(shí)間同步。

更新約束一共分為三個(gè)步驟

  1. 創(chuàng)建鍵盤彈出和隱藏系統(tǒng)通知
  2. 實(shí)現(xiàn)通知方法
  3. 通過調(diào)用needsUpdateConstraints及updateConstraintsIfNeeded實(shí)現(xiàn)動(dòng)畫更新

示例Demo:

觸發(fā)彈出或回收鍵盤通知方法中改變約束

1、首先創(chuàng)建鍵盤彈出和隱藏系統(tǒng)通知

// 鍵盤將要彈出
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
        
// 鍵盤將要回彈
NotificationCenter.default.addObserver(self, selector: #selector(self.keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)

2旦事、實(shí)現(xiàn)通知方法

    // MARK: - 鍵盤將要彈出
    func keyboardWillShow(notification: Notification) {
        let userInfo = notification.userInfo
        let aValue = userInfo?[UIKeyboardAnimationDurationUserInfoKey]
        SLLog("彈出\(aValue!)")
        
        // 判斷是否是第一次觸發(fā)開始編輯魁巩,如果是第一次則改變約束
        if isUpdataExpand == false {
            updateWithExpand(isExpanded: true, animated: true, duration: aValue! as! TimeInterval)
            isUpdataExpand = true
        }
    }
    
    // MARK: - 鍵盤將要回收
    func keyboardWillHide(notification: Notification) {
        let userInfo = notification.userInfo
        let aValue = userInfo?[UIKeyboardAnimationDurationUserInfoKey]
        SLLog("回收\(aValue!)")
        updateWithExpand(isExpanded: false, animated: true, duration: aValue! as! TimeInterval)
        // 回收把isUpdataExpand設(shè)置為false
        isUpdataExpand = false
    }

3.更新約束

    // MARK: - 更新約束
    func updateWithExpand(isExpanded:Bool, animated:Bool, duration:TimeInterval = 0.25) {
        // 重要:更新約束需要調(diào)用updateConstraints閉包
        soolifeImg.snp.updateConstraints { (make) in
            if isExpanded == false{
                make.centerX.equalTo(self)
                make.width.equalTo(SCREEN_W/4)
                make.top.equalTo(self.snp.top).offset(AD_HEIGHT(90))
                make.height.equalTo(AD_HEIGHT(120))
            }else{
                make.centerX.equalTo(self)
                make.width.equalTo(SCREEN_W/5)
                make.top.equalTo(self.snp.top).offset(AD_HEIGHT(50))
                make.height.equalTo(AD_HEIGHT(80))
            }
        }
        
        accountIT.snp.updateConstraints { (make) in
            make.left.equalTo(self.snp.left).offset(AD_WIDTH(15))
            make.right.equalTo(self.snp.right).offset(AD_WIDTH(-15))
            make.height.equalTo(AD_HEIGHT(45))
            if isExpanded == false{
                make.top.equalTo(soolifeImg.snp.bottom).offset(AD_HEIGHT(60))
            }else{
                make.top.equalTo(soolifeImg.snp.bottom).offset(AD_HEIGHT(40))
            }
        }
        
        passwordIT.snp.updateConstraints { (make) in
            make.left.equalTo(self.snp.left).offset(AD_WIDTH(15))
            make.right.equalTo(self.snp.right).offset(AD_WIDTH(-15))
            make.height.equalTo(AD_HEIGHT(45))
            make.top.equalTo(accountIT.snp.bottom).offset(AD_HEIGHT(5))
        }
        
        loginBtn.snp.updateConstraints { (make) in
            make.top.equalTo(passwordIT.snp.bottom).offset(AD_HEIGHT(40))
            make.left.equalTo(self.snp.left).offset(AD_WIDTH(20))
            make.right.equalTo(self.snp.right).offset(AD_WIDTH(-20))
            make.height.equalTo(AD_HEIGHT(40))
        }
        
        
        if animated == true {
            // 告訴self.view約束需要更新
            self.needsUpdateConstraints()
            // 調(diào)用此方法告訴self.view檢測是否需要更新約束,若需要?jiǎng)t更新姐浮,下面添加動(dòng)畫效果才起作用
            self.updateConstraintsIfNeeded()
            // 更新動(dòng)畫
            UIView.animate(withDuration: duration, animations: {
                self.layoutIfNeeded()
            })
        }
    }

完整Demo

傳送門

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谷遂,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子卖鲤,更是在濱河造成了極大的恐慌肾扰,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蛋逾,死亡現(xiàn)場離奇詭異集晚,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)换怖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門甩恼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人沉颂,你說我怎么就攤上這事条摸。” “怎么了铸屉?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵钉蒲,是天一觀的道長。 經(jīng)常有香客問我彻坛,道長顷啼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任昌屉,我火速辦了婚禮钙蒙,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘间驮。我一直安慰自己躬厌,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布竞帽。 她就那樣靜靜地躺著扛施,像睡著了一般。 火紅的嫁衣襯著肌膚如雪屹篓。 梳的紋絲不亂的頭發(fā)上疙渣,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音堆巧,去河邊找鬼妄荔。 笑死泼菌,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的懦冰。 我是一名探鬼主播灶轰,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼刷钢!你這毒婦竟也來了笋颤?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤内地,失蹤者是張志新(化名)和其女友劉穎伴澄,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阱缓,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡非凌,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了荆针。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敞嗡。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖航背,靈堂內(nèi)的尸體忽然破棺而出喉悴,到底是詐尸還是另有隱情,我是刑警寧澤玖媚,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布箕肃,位于F島的核電站,受9級(jí)特大地震影響今魔,放射性物質(zhì)發(fā)生泄漏勺像。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一错森、第九天 我趴在偏房一處隱蔽的房頂上張望吟宦。 院中可真熱鬧,春花似錦涩维、人聲如沸殃姓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锋叨,卻和暖如春垄分,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背娃磺。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工薄湿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓豺瘤,卻偏偏與公主長得像吆倦,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子坐求,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容