項目中都是用別人封裝好的第三方:masonry加缘,跟未封裝的一比不得不說masony的強大沿侈。前段時間斗忌,一朋友說到約束這塊质礼,在做framework的時候要使用到約束(雖然現(xiàn)在自己還寫不出啥好的framework,但是知識靠積累嘛织阳,不急總有自己發(fā)光的時候)眶蕉,但是總不能強迫讓引用你的framework的開發(fā)者引入第三方庫吧!最近也空閑了唧躲,默默的去找百度造挽,然后整理了一下NSLayoutConstraint碱璃,廢話就不說了,開始干貨刽宪。
NSLayoutConstraint
xib中厘贼,可以用拖拽添加約束界酒,也可以把約束給拖拽出來用代碼來設置約束條件圣拄。看來可視化的約束還是必要學的毁欣。
添加NSLayoutConstraint約束的時候庇谆,先看下控件是否關閉了TranslatesAutoresizingMaskIntoConstraints屬性,如果沒有關閉系統(tǒng)在運行時會自動將Autoresizing Mask轉為Auto Layout的約束凭疮,從而造成沖突饭耳。報錯如下:
方法constraintWithItem的使用
/* Create constraints explicitly. Constraints are of the form "view1.attr1 = view2.attr2 * multiplier + constant"
If your equation does not have a second view and attribute, use nil and NSLayoutAttributeNotAnAttribute.
*/
+(instancetype)constraintWithItem:(id)view1 attribute:(NSLayoutAttribute)attr1 relatedBy:(NSLayoutRelation)relation toItem:(nullable id)view2 attribute:(NSLayoutAttribute)attr2 multiplier:(CGFloat)multiplier constant:(CGFloat)c;
Item :view1是你需要設置約束的視圖,view1對應需要做的約束
attribute(attr1):NSLayoutAttribute执解,view1需要約束的位置例如:它的頂部NSLayoutAttributeTop寞肖、底部NSLayoutAttributeBottom、左邊NSLayoutAttributeLeft衰腌、右邊NSLayoutAttributeRight等新蟆。
relatedBy:NSLayoutRelation,view1與view2的視圖關系右蕊,例如:NSLayoutRelationEqual琼稻。
toItem:view1需要參照約束的對象view2,view2可為空饶囚。如果view2為空帕翻,view2的約束為NSLayoutAttributeNotAnAttribute無屬性。
attribute(attr2):NSLayoutAttribute萝风,參考attr1
multiplier:比例view1與view2的倍數(shù)嘀掸,通常為1.0,當你想要view1的寬度等于view2的寬度一半的時候你只需要設置為0.5规惰,constant為0就OK睬塌。
constant:view1相對view2偏移的像素距離。
NSLayoutAttribute
typedef NS_ENUM(NSInteger, NSLayoutAttribute) {
NSLayoutAttributeLeft = 1, //左側
NSLayoutAttributeRight, //右側
NSLayoutAttributeTop, //上方
NSLayoutAttributeBottom, //下方
NSLayoutAttributeLeading, //首部
NSLayoutAttributeTrailing, //尾部
NSLayoutAttributeWidth, //寬度
NSLayoutAttributeHeight, //高度
NSLayoutAttributeCenterX, //X軸中心
NSLayoutAttributeCenterY, //Y軸中心
NSLayoutAttributeLastBaseline, //文本底標線
NSLayoutAttributeBaseline NS_SWIFT_UNAVAILABLE("Use 'lastBaseline' instead") = NSLayoutAttributeLastBaseline,
NSLayoutAttributeFirstBaseline NS_ENUM_AVAILABLE_IOS(8_0),
NSLayoutAttributeLeftMargin NS_ENUM_AVAILABLE_IOS(8_0),//左邊距
NSLayoutAttributeRightMargin NS_ENUM_AVAILABLE_IOS(8_0),//右邊距
NSLayoutAttributeTopMargin NS_ENUM_AVAILABLE_IOS(8_0),//上方邊距
NSLayoutAttributeBottomMargin NS_ENUM_AVAILABLE_IOS(8_0),//下方邊距
NSLayoutAttributeLeadingMargin NS_ENUM_AVAILABLE_IOS(8_0),//首部邊距
NSLayoutAttributeTrailingMargin NS_ENUM_AVAILABLE_IOS(8_0),//尾部邊距
NSLayoutAttributeCenterXWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),//X軸中心邊距
NSLayoutAttributeCenterYWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),//Y軸中心邊距
NSLayoutAttributeNotAnAttribute = 0//無屬性
};
NSLayoutRelation
typedef NS_ENUM(NSInteger, NSLayoutRelation) {
NSLayoutRelationLessThanOrEqual = -1, //小于或等于
NSLayoutRelationEqual = 0, //等于
NSLayoutRelationGreaterThanOrEqual = 1, //大于或等于
};
使用栗子
_logoLabel = [[UILabel alloc] init];
[_logoLabel setText:@"上方84卿拴,高度17衫仑,水平居中"];
[_logoLabel setFont:[UIFont systemFontOfSize:17]];
[_logoLabel setTextColor:[UIColor redColor]];
[_logoLabel setTranslatesAutoresizingMaskIntoConstraints:NO];//別忘了這個
[self.view addSubview:_logoLabel];
約束
//logoLabel的上方距離self.view 的上方想下84
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.logoLabel attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:84]];
//logoLabel的X軸中心點等于self.view 的X軸中心點,用來讓logoLabel在view上水平居中
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.logoLabel attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:1]];
//logoLabel的寬度堕花,沒有比較的對象toItem:nil 文狱,所以attr2的屬性為NSLayoutAttributeNotAnAttribute
[self.view addConstraint:[NSLayoutConstraint constraintWithItem:self.logoLabel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:17]];
看下效果圖:
相關屬性說明有了,使用栗子有了缘挽,剩下的約束就看自己了哈瞄崇。當然呻粹,記得如果你要的約束距離是動態(tài)的別把constant設置為固定值,畢竟沒有辣么智能知道你是相對于什么屏幕像素來做約束的苏研。在強調一下等浊,如果要動態(tài)的,別給constant設置固定值摹蘑、別給constant設置固定值筹燕、別給constant設置固定值,強調三遍衅鹿。