[Swift]AutoLayout簡(jiǎn)單封裝

簡(jiǎn)單演示

一罐柳、前言

說到Swift中對(duì)AutoLayout的封裝王者無疑是SnapKit,它簡(jiǎn)單方便的調(diào)用無疑深得人心拂到。筆者今天要講的是利用Swift的特性對(duì)AutoLayout進(jìn)行簡(jiǎn)單的封裝帅刊。相比較SnapKit而言走芋,它的使用不能說更簡(jiǎn)單方便全闷,但實(shí)現(xiàn)可以說是一目了然叉寂,也算是對(duì)AutoLayout的介紹。下面將會(huì)講封裝的思路以及使用介紹总珠。

二屏鳍、JYAutoLayout的封裝思路

如上面演示圖的所示,所有橙色 和 白色的View的布局均相對(duì)于灰色的大View 而每個(gè)view的布局只需要短短的一行代碼:

       UIedgeView(htrBtn).left(centerBtn,c:8).alignTop(centerBtn).size(btnSize).end()

2.1NSLayoutConstraint約束創(chuàng)建

 convenience init(item view1: AnyObject, attribute attr1: NSLayoutAttribute, relatedBy relation: NSLayoutRelation, toItem view2: AnyObject?, attribute attr2: NSLayoutAttribute, multiplier: CGFloat, constant c: CGFloat)
   這是一條約束的創(chuàng)建局服,它的約束關(guān)系是 view1.attr1 < = > view2.attr2 * multiplier + c
    所以我們可以看到?jīng)Q定一個(gè)View1的某條約束所需的參數(shù)有:
var View2    : UIView?                    相對(duì)于哪個(gè)view 即view2
var Attribute1 : NSLayoutAttribute?     view1  的NSLayoutAttribute
var Attribute2 : NSLayoutAttribute?     view2  的NSLayoutAttribute
var Multiplier : CGFloat?                   比例系數(shù)
var Equal = NSLayoutRelation.Equal        大于 等于 小于
var offset : CGFloat                      偏移 
var priority : UILayoutPriority           當(dāng)然還有當(dāng)前約束的優(yōu)先級(jí)

2.2NSLayoutAttribute 包含有

case Left                          //左側(cè)
case Right                        //右側(cè)
case Top                          //上方
case Bottom                       //下方
case Leading                      //首部
case Trailing                     //尾部
case Width                        //寬度
case Height                       //高度
case CenterX                      //X軸中心
case CenterY                      //Y軸中心
case Baseline                     //文本底標(biāo)線
case NotAnAttribute               //沒有屬性
在iOS8.0下又多了 一些邊界屬性
case LeftMargin
case RightMargin
case TopMargin
case BottomMargin
case LeadingMargin
case TrailingMargin
case CenterXWithinMargins
case CenterYWithinMargins

注:Left/Right 和 Leading/Trailing的區(qū)別是Left/Right永遠(yuǎn)是指左右钓瞭,而Leading/Trailing在某些從右至左習(xí)慣的地區(qū)會(huì)變成,leading是右邊腌逢,trailing是左邊降淮。

2.3簡(jiǎn)化封裝

以view的上邊為例我們可以提供下面一個(gè)方法來表示一條約束參數(shù)

private func top(v:UIView! , c : CGFloat , a : NSLayoutAttribute = NSLayoutAttribute.Bottom , m : CGFloat = 1.0 , e : NSLayoutRelation = NSLayoutRelation.Equal, p : UILayoutPriority = UILayoutPriorityDefaultHigh) -> UIedgeView {
   
}

view的top 與 v 的 a * m + c 當(dāng)然還有優(yōu)先級(jí)
swift有個(gè)非常好的地方,那就是只要設(shè)置了默認(rèn)參數(shù)就可以不用傳該參數(shù)搏讶,而在我們實(shí)際使用中 一般都是 等于 而比例細(xì)數(shù)也基本 是1.0佳鳖,所以通常 只要設(shè)置 v(view)c (偏移) a(對(duì)應(yīng)的邊)即可,而優(yōu)先級(jí)也基本不使用媒惕。

又考慮到 top 對(duì) top 與 top 對(duì) Bottom 是極為常見的所以又以方法名來區(qū)分 以 alignTop方法來表示 top 對(duì) top關(guān)系 而 top方法默認(rèn)表示 top 對(duì) Bottom關(guān)系 當(dāng)然top方法仍可以傳入NSLayoutAttribute參數(shù)系吩,這樣%90的情況下我們只需要設(shè)置兩個(gè)參數(shù) view 與 c 就可以描述一條參數(shù)。如: htrBtn.left(centerBtn,c:8)
同理對(duì) Bottom Right Left Width Height CenterX CenterY做了處理妒蔚。

2.4鏈?zhǔn)骄幊痰膶?shí)現(xiàn)

swift的方法調(diào)用都是點(diǎn)語(yǔ)法穿挨,再也不像OC那樣需要[],我們只需要在一個(gè)方法結(jié)束時(shí)返回self 就可以無限調(diào)用

 @discardableResult  func top(_ v: UIView! , c: CGFloat = 0 , a: NSLayoutAttribute = NSLayoutAttribute.bottom , m: CGFloat = 1.0 , e: NSLayoutRelation = NSLayoutRelation.equal, p: UILayoutPriority = UILayoutPriorityDefaultHigh) -> UIedgeView {
    
    let layout = JYlayout(v: v, c: c, a1:NSLayoutAttribute.top , a2: a, m: m, e: e, p: p)
    dict .setValue(layout, forKey: ffTop)
    return self
}

2.5約束的添加 end() remake() update()

對(duì)于這么一個(gè)布局 htrBtn.left(centerBtn,c:8).alignTop(centerBtn).size(btnSize) 都是約束的準(zhǔn)備只是將約束所需要的參數(shù)保存到了UIedgeView這么一個(gè)對(duì)象中
而 end() remake() update() 才是添加相應(yīng)的約束
end() 什么都不管只管添加約束
remake() 會(huì)將之前的約束全部刪除,重新添加
update() 會(huì)根據(jù)當(dāng)前代碼所設(shè)計(jì)到的約束肴盏,而刪除對(duì)應(yīng)約束科盛,比如 btn.centerX(self).size(100, h: 100).update() 它涉及到了 centerX Width Height 的約束那么它會(huì)將之前添加的關(guān)于 centerX Width Height 的所有約束刪除然后添加。

注意:1.remake() update() 刪除約束使用的是以下方法:
public func removeConstraint(constraint: NSLayoutConstraint) // This method will be deprecated in a future release and should be avoided. Instead set NSLayoutConstraint's active property to NO.
這個(gè)方法將會(huì)在將來的版本中被棄用,應(yīng)該避免菜皂。蘋果也不太建議刪除約束再添加贞绵,如果有約束改變應(yīng)當(dāng)記錄約束直接修改,可以參考Demo中的AnimDemoView1恍飘,或者添加多個(gè)約束使用修改優(yōu)先級(jí)來達(dá)到改變的目的榨崩,可以參考Demo中的AnimDemoView2

2.不要使用 btn.centerX(self).centerX(view2).end() 這種寫法是錯(cuò)誤的,有效約束只會(huì)是centerX(view2)章母。如有需要應(yīng)當(dāng)如下:

   btn.makeConstraint { (make) in
        make.centerX(reference1,p:priorityMedium).end()
        make.centerX(reference2,p:priorityHigh).end()
   }

7.提供的方法說明

top                 默認(rèn) top 對(duì) bottom
alignTop            top 對(duì) top
left                默認(rèn) left 對(duì) right
alignLeft           left 對(duì) left
bottom              默認(rèn) bottom 對(duì) top
alignBottom         bottom 對(duì) bottom
right               默認(rèn) right 對(duì) left
alignRight          right 對(duì) right
centerX             默認(rèn) centerX 對(duì) centerX    
centerY             默認(rèn) centerY 對(duì) centerY    
center              默認(rèn) centerX 對(duì) centerX centerY 對(duì) centerY
height              有對(duì)view 的 height 也有提供 數(shù)字 50
width               有對(duì)view 的 width 也有提供  數(shù)字 50
size                有對(duì)view 的 width height 也有提供 CGsize

方法的參數(shù)描述
@discardableResult  func top(_ v: UIView! , c: CGFloat = 0 , a: NSLayoutAttribute = NSLayoutAttribute.bottom , m: CGFloat = 1.0 , e: NSLayoutRelation = NSLayoutRelation.equal, p: UILayoutPriority = UILayoutPriorityDefaultHigh) -> UIedgeView {
    
    let layout = JYlayout(v: v, c: c, a1:NSLayoutAttribute.top , a2: a, m: m, e: e, p: p)
    dict .setValue(layout, forKey: ffTop)
    return self
}

v :參照的view
c : 偏移
m : 比例系數(shù)
a : 參照view的NSLayoutAttribute
e : NSLayoutRelation.Equal 大于 等于 小于
p : 優(yōu)先級(jí)

關(guān)于優(yōu)先級(jí)定義:
public let  priorityHighTop = (UILayoutPriority)(UILayoutPriorityDefaultHigh + 1); 
public let  priorityHigh = UILayoutPriorityDefaultHigh;
public let  priorityMedium = (UILayoutPriority)(500);
public let  priorityLow = UILayoutPriorityDefaultLow;
public let  priorityRequired = UILayoutPriorityRequired;
public let  priorityFittingSizeLevel = UILayoutPriorityFittingSizeLevel;

如果還需要 Baseline 等相關(guān)關(guān)系可自行封裝母蛛,都是體力活

三、結(jié)尾

JYAutoLayout是筆者在Swift2 時(shí)代的一個(gè)練手產(chǎn)物乳怎,利用了Swift點(diǎn)語(yǔ)法調(diào)用以及參數(shù)可預(yù)設(shè)的特性對(duì)AutoLayout的封裝彩郊,使用也是簡(jiǎn)單方便。SnapKit雖然使用簡(jiǎn)單蚪缀,但在我看來它封裝的過于復(fù)雜了焦辅,帶來的收益(簡(jiǎn)單調(diào)用)完全可以用更方便的方式封裝。相信大家在升級(jí)到Xcode8時(shí)看到SnapKit爆紅時(shí)有多么萌比椿胯,我們也只能等待作者更新筷登。與其依賴別人,不如依賴自己哩盲,JYAutoLayout的封裝相當(dāng)簡(jiǎn)單相信一個(gè)對(duì)AutoLayout有所了解的同學(xué)在看完筆者的簡(jiǎn)單說明后自己就可以寫出來了前方,在之上擴(kuò)展優(yōu)化更不在話下。

如果我的文章對(duì)你有幫助或者給了你一些啟發(fā)廉油,希望你能在github給個(gè)小星星惠险,如果你在使用過程中遇到了Bug請(qǐng)留言反饋,我會(huì)及時(shí)解決抒线。歡迎轉(zhuǎn)載(在文章開頭標(biāo)明來源即可)班巩。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市嘶炭,隨后出現(xiàn)的幾起案子抱慌,更是在濱河造成了極大的恐慌逊桦,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,546評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抑进,死亡現(xiàn)場(chǎng)離奇詭異强经,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)寺渗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,224評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門匿情,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人信殊,你說我怎么就攤上這事炬称。” “怎么了涡拘?”我有些...
    開封第一講書人閱讀 164,911評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵玲躯,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我鲸伴,道長(zhǎng)府蔗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,737評(píng)論 1 294
  • 正文 為了忘掉前任汞窗,我火速辦了婚禮姓赤,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘仲吏。我一直安慰自己不铆,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,753評(píng)論 6 392
  • 文/花漫 我一把揭開白布裹唆。 她就那樣靜靜地躺著誓斥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪许帐。 梳的紋絲不亂的頭發(fā)上劳坑,一...
    開封第一講書人閱讀 51,598評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音成畦,去河邊找鬼距芬。 笑死,一個(gè)胖子當(dāng)著我的面吹牛循帐,可吹牛的內(nèi)容都是我干的框仔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,338評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼拄养,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼离斩!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,249評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤跛梗,失蹤者是張志新(化名)和其女友劉穎寻馏,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體茄袖,經(jīng)...
    沈念sama閱讀 45,696評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡操软,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,888評(píng)論 3 336
  • 正文 我和宋清朗相戀三年嘁锯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宪祥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,013評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡家乘,死狀恐怖蝗羊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情仁锯,我是刑警寧澤耀找,帶...
    沈念sama閱讀 35,731評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站业崖,受9級(jí)特大地震影響野芒,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜双炕,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,348評(píng)論 3 330
  • 文/蒙蒙 一狞悲、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧妇斤,春花似錦摇锋、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,929評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至死相,卻和暖如春融求,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背算撮。 一陣腳步聲響...
    開封第一講書人閱讀 33,048評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工生宛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人钮惠。 一個(gè)月前我還...
    沈念sama閱讀 48,203評(píng)論 3 370
  • 正文 我出身青樓茅糜,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親素挽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蔑赘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,960評(píng)論 2 355

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