NSLayoutConstraint

繼承自:NSObject
**Available in iOS 6.0 and later **

constraint定義了一種位置關系锹雏,通過約束來將兩個UI對象的位置確定在屏幕上。每個約束遵循如下的這個線性公式:

item1.attribute1 = multiplier × item2.attribute2 + constant

在這個等式中术奖,attribute1和attribute2是兩個自動布局的變量礁遵,就是通過它們來適配不同的屏幕尺寸。其他的值在你創(chuàng)建約束的時候就該定下來了采记。舉例來說佣耐,如果你要定義兩個按鈕之間的相對位置,你可能會說:“第二個按鈕的最左邊要距離第一個按鈕的最右邊有8個point的距離唧龄〖孀”這個約束關系的線性公式就如下所示:

// positive values move to the right in left-to-right languages like English.
button2.leading = 1.0 × button1.trailing + 8.0

隨后自動布局就會自動調(diào)整兩個按鈕左右邊緣的位置,直到上述等式左右相等既棺。這里值得注意的是讽挟,自動布局并不是單方面地調(diào)整一個按鈕來滿足條件,而是在需要的時候調(diào)整其中的任意一個援制,甚至兩個按鈕的位置都調(diào)整戏挡。

等式相等意味著,你可以改變item的順序晨仑,也就是說你可以對這個等式做隨意的一次方程計算。經(jīng)過改變拆檬,等式可以更好地表達兩個item之間的約束關系洪己。提醒一句,改變等式別忘了隨之改變multiplier(系數(shù))和constant(常數(shù))竟贯。舉個例子答捕,下面的兩個等式就表達相同的約束:

// These equations produce identical constraints
button2.leading = 1.0 × button1.trailing + 8.0
button1.trailing = 1.0 × button2.leading - 8.0

一個有效的布局方案會有一套完整的約束,這意味著由許多等式組成屑那,這些等式有且僅有唯一一個解來定位一個item拱镐。要看怎么來定義一個有效布局艘款,請移步 Auto Layout Guide中的Resolving Auto Layout Issues

另外,約束也不只有兩者相等這一種沃琅,還可以用大于等于(>=)哗咆,或者小于等于(<=)來描述約束關系。約束還有優(yōu)先級益眉,范圍是1~1000晌柬,1000代表必須實現(xiàn)(required),此外都是根據(jù)優(yōu)先級可選擇實現(xiàn)(optional)郭脂。默認優(yōu)先級都是1000年碘。

自動布局實現(xiàn)了所有必須實現(xiàn)的約束之后,會根據(jù)優(yōu)先級順序來嘗試去實現(xiàn)可選約束展鸡。如果實現(xiàn)不了屿衅,就盡可能接近要求,然后繼續(xù)處理下個可選約束莹弊。

通過這套等式涤久、不等式、優(yōu)先級的組合箱硕,你完全可以定義一套極具靈活性的布局拴竹,來讓你的UI元素自適應任何變化。


創(chuàng)建約束

+ (NSArray<__kindof NSLayoutConstraint *> *)constraintsWithVisualFormat:(NSString *)format
                                                                options:(NSLayoutFormatOptions)opts
                                                                metrics:(NSDictionary<NSString *,
                                                                                 id> *)metrics
                                                                  views:(NSDictionary<NSString *,
                                                                                 id> *)views

根據(jù)Visual Format Language以及對齊選擇項來創(chuàng)建一組對象的約束

+ (instancetype)constraintWithItem:(id)view1
                         attribute:(NSLayoutAttribute)attr1
                         relatedBy:(NSLayoutRelation)relation
                            toItem:(id)view2
                         attribute:(NSLayoutAttribute)attr2
                        multiplier:(CGFloat)multiplier
                          constant:(CGFloat)c

最常用的約束方法剧罩,根據(jù)兩個item的指定attribute來約束item的位置栓拜,返回一個NSLayoutConstraint對象。iOS6.0

參數(shù) 含義
view1 第一個item
attr1 item1的參考屬性
relation 兩個item參考屬性之間的關系惠昔,詳見NSLayoutRelation
view2 item1的參照物幕与,item2
multiplier item2的參考屬性帶入計算時需要縮放的倍數(shù)
c item2的屬性乘以倍數(shù)之后加上這個常量,來得到約束的最終結果

論述:也可能出現(xiàn)這樣的情況镇防,item1的這個約束并不需要參照物item2(比如說約束寬度)啦鸣,這時候在item2上代入nil,attr2代入NSLayoutAttributeNotAnAttribute来氧。


激活或關閉約束

@property(getter=isActive) BOOL active //iOS8.0

這個屬性可以激活或者關閉一個約束诫给,只有激活狀態(tài)的約束才能影響最終的布局。需要注意的是啦扬,如果兩個items的不在同一個界面上中狂,則計算結果會報錯。新創(chuàng)建的約束對象的狀態(tài)默認為關閉扑毡。

你可以在兩個items所在的view上調(diào)用addConstraint:或者removeConstraint:來激活或者關閉一個約束胃榕。但更方便的是直接改變這個屬性來替代調(diào)用這兩個方法。

+ (void)activateConstraints:(NSArray<NSLayoutConstraint *> *)constraints //iOS8.0
+ (void)deactivateConstraints:(NSArray<NSLayoutConstraint *> *)constraints //iOS8.0

這兩個方法可以一次性激活/關閉一堆約束的激活狀態(tài)瞄摊。通常來講勋又,用這兩個方法比一個個修改約束的active屬性在性能上更具優(yōu)勢苦掘。


約束內(nèi)部數(shù)據(jù)的接口

@property UILayoutPriority priority //(iOS6.0)

這里再提一遍,約束并不是非真即假的楔壤,而且如果一個約束并不是必須實現(xiàn)的鹤啡,那么自動布局也只會去盡可能貼近等式、不等式的計算結果挺邀。

一個約束被添加并激活了之后揉忘,它的優(yōu)先級就不能在必須實現(xiàn)和可選實現(xiàn)中來回修改了。但是如果同是可選實現(xiàn)的話端铛,還是能夠在約束激活后即時修改優(yōu)先級的具體數(shù)值泣矛。

@property(readonly, assign) id firstItem //iOS6.0
@property(readonly) NSLayoutAttribute firstAttribute //iOS6.0
@property(readonly) NSLayoutRelation relation //iOS6.0
@property(readonly, assign) id secondItem //iOS6.0
@property(readonly) NSLayoutAttribute secondAttribute //iOS6.0
@property(readonly) CGFloat multiplier //iOS6.0

上略

@property CGFloat constant //iOS6.0

和其他屬性不同,constant在約束創(chuàng)建之后仍可以修改禾蚕。在現(xiàn)有的約束上修改constant要比移除一個約束您朽,再新建一個除了constant外沒啥區(qū)別的約束要效率得多。


標識一個約束

@property(copy) NSString *identifier //iOS7.0

約束的標識從description中就能得到


Controlling Constraint Archiving

@property BOOL shouldBeArchived //iOS6.0

When a view is archived, it archives some but not all constraints in its constraints
array. The value ofshouldBeArchived
informs the view if a particular constraint should be archived by the view.
If a constraint is created at runtime in response to the state of the object, it isn't appropriate to archive the constraint. Instead you archive the state that gives rise to the constraint. The default value for this property is NO


枚舉常量

enum { 
NSLayoutRelationLessThanOrEqual = -1, 
NSLayoutRelationEqual = 0, 
NSLayoutRelationGreaterThanOrEqual = 1,
};
typedef NSInteger NSLayoutRelation; //iOS6.0
  • NSLayoutRelationLessThanOrEqual
    前一個屬性小于等于后一個屬性
  • NSLayoutRelationEqual
    兩個屬性完全相等
  • NSLayoutRelationGreaterThanOrEqual
    前一個屬性大于等于后一個屬性
typedef enum: NSInteger { 
NSLayoutAttributeLeft = 1, 
NSLayoutAttributeRight, 
NSLayoutAttributeTop, 
NSLayoutAttributeBottom, 
NSLayoutAttributeLeading, 
NSLayoutAttributeTrailing, 
NSLayoutAttributeWidth, 
NSLayoutAttributeHeight, 
NSLayoutAttributeCenterX, 
NSLayoutAttributeCenterY, 
NSLayoutAttributeBaseline, 
NSLayoutAttributeLastBaseline = NSLayoutAttributeBaseline, 
NSLayoutAttributeFirstBaseline, 

NSLayoutAttributeLeftMargin, 
NSLayoutAttributeRightMargin, 
NSLayoutAttributeTopMargin, 
NSLayoutAttributeBottomMargin, 
NSLayoutAttributeLeadingMargin, 
NSLayoutAttributeTrailingMargin, 
NSLayoutAttributeCenterXWithinMargins, 
NSLayoutAttributeCenterYWithinMargins,
 
NSLayoutAttributeNotAnAttribute = 0
} NSLayoutAttribute; //iOS6.0 iOS8.0
  • NSLayoutAttributeLeading
    在習慣由左向右看的地區(qū),相當于NSLayoutAttributeLeft。在習慣從右至左看的地區(qū)誊役,相當于NSLayoutAttributeRight
  • NSLayoutAttributeTrailing
    在習慣由左向右看的地區(qū),相當于NSLayoutAttributeRight讯屈。在習慣從右至左看的地區(qū),相當于NSLayoutAttributeLeft
  • magin
    一系列邊界約束屬性如下圖所示:


    36R3qqu.png
  • NSLayoutAttributeNotAnAttribute
    約束用不著第二個item的時候县习,第二個屬性處選填
enum { 
/* choose only one of these */ 
NSLayoutFormatAlignAllLeft = NSLayoutAttributeLeft, 
NSLayoutFormatAlignAllRight = NSLayoutAttributeRight, 
NSLayoutFormatAlignAllTop = NSLayoutAttributeTop, 
NSLayoutFormatAlignAllBottom = NSLayoutAttributeBottom, 
NSLayoutFormatAlignAllLeading = NSLayoutAttributeLeading, 
NSLayoutFormatAlignAllTrailing = NSLayoutAttributeTrailing, 
NSLayoutFormatAlignAllCenterX = NSLayoutAttributeCenterX, 
NSLayoutFormatAlignAllCenterY = NSLayoutAttributeCenterY, 
NSLayoutFormatAlignAllBaseline = NSLayoutAttributeBaseline, 

NSLayoutFormatAlignmentMask = 0xFF, 

/* choose only one of these three */ 
NSLayoutFormatDirectionLeadingToTrailing = 0 << 8, // default  
NSLayoutFormatDirectionLeftToRight = 1 << 8, 
NSLayoutFormatDirectionRightToLeft = 2 << 8, 

NSLayoutFormatDirectionMask = 0x3 << 8,
};
typedef NSUInteger NSLayoutFormatOptions;

對齊選擇項涮母,字面意思不累述

enum { 
UILayoutPriorityRequired = 1000, 
UILayoutPriorityDefaultHigh = 750, 
UILayoutPriorityDefaultLow = 250, 
UILayoutPriorityFittingSizeLevel = 50,
};typedef float UILayoutPriority;

iOS7.1后不使用,直接根據(jù)需要設定約束的priority屬性值即可躁愿。

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末叛本,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子彤钟,更是在濱河造成了極大的恐慌来候,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逸雹,死亡現(xiàn)場離奇詭異营搅,居然都是意外死亡,警方通過查閱死者的電腦和手機梆砸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門剧防,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人辫樱,你說我怎么就攤上這事】”樱” “怎么了狮暑?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵鸡挠,是天一觀的道長。 經(jīng)常有香客問我搬男,道長拣展,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任缔逛,我火速辦了婚禮备埃,結果婚禮上,老公的妹妹穿的比我還像新娘褐奴。我一直安慰自己按脚,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布敦冬。 她就那樣靜靜地躺著辅搬,像睡著了一般。 火紅的嫁衣襯著肌膚如雪脖旱。 梳的紋絲不亂的頭發(fā)上堪遂,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機與錄音萌庆,去河邊找鬼溶褪。 笑死,一個胖子當著我的面吹牛践险,可吹牛的內(nèi)容都是我干的猿妈。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼捏境,長吁一口氣:“原來是場噩夢啊……” “哼于游!你這毒婦竟也來了?” 一聲冷哼從身側響起垫言,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤贰剥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后筷频,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蚌成,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年凛捏,在試婚紗的時候發(fā)現(xiàn)自己被綠了担忧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡坯癣,死狀恐怖瓶盛,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤惩猫,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布芝硬,位于F島的核電站,受9級特大地震影響轧房,放射性物質(zhì)發(fā)生泄漏拌阴。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一奶镶、第九天 我趴在偏房一處隱蔽的房頂上張望迟赃。 院中可真熱鬧,春花似錦厂镇、人聲如沸纤壁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽摄乒。三九已至,卻和暖如春残黑,著一層夾襖步出監(jiān)牢的瞬間馍佑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工梨水, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留拭荤,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓疫诽,卻偏偏與公主長得像舅世,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子奇徒,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

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