相信大家在iOS的開發中,經常會遇到一些不明原因的約束警告,有時候按百度到的方法試一下就好了,有時候卻不行.而且下一次可能還會出現,比如下面這種約束的報錯
Unable to simultaneously satisfy constraints.
Probably at least one of the constraints in the following list is one you don't want.
Try this:
(1) look at each constraint and try to figure out which you don't expect;
(2) find the code that added the unwanted constraint or constraints and fix it.
(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x11d748d0 V:[UITextView:0xc1bb000(65)]>",
"<NSLayoutConstraint:0x11d77620 V:[UIButton:0x11d71cf0(44)]>",
"<NSLayoutConstraint:0x11d7be30 V:[UIButton:0x11d79e70(43)]>",
"<NSLayoutConstraint:0xa1980d0 V:|-(134)-[UITextView:0xc1bb000] (Names: '|':UIView:0xa1afba0 )>",
"<NSLayoutConstraint:0xa199ed0 UITextView:0xc1bb000.centerY == UIButton:0x11d71cf0.centerY>",
"<NSLayoutConstraint:0xa199e50 V:[UIButton:0x11d79e70]-(61)-[UIButton:0x11d71cf0]>",
"<NSLayoutConstraint:0xa199cb0 V:|-(40)-[UIButton:0x11d79e70] (Names: '|':UIView:0xa1afba0 )>"
)
Will attempt to recover by breaking constraint
<NSLayoutConstraint:0x11d748d0 V:[UITextView:0xc1bb000(65)]>
Break on objc_exception_throw to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.
複製程式碼
一般來說,出現這種警告有兩種情況:
- 使用xib中自帶的view,對其中子控制元件新增了Autolayout約束,在呼叫xib後又調整了view的frame
- 純程式碼方式使用Autolayout,但沒有對使用的View的translatesAutoresizingMaskIntoConstraints的屬性設定為NO.
- 如果是從程式碼層面開始使用Autolayout,需要對使用的View的translatesAutoresizingMaskIntoConstraints的屬性設定為NO. 即可開始通過程式碼新增Constraint,否則View還是會按照以往的autoresizingMask進行計算. 而在Interface Builder中預設勾選了Ues Autolayout,IB生成的控制元件的translatesAutoresizingMaskIntoConstraints屬性都會被預設設定NO.
UIView *redView = [[UIView alloc] init];
redView.backgroundColor= [UIColorredColor];
//禁止autoresizing自動轉換為約束(特別重要)
redView.translatesAutoresizingMaskIntoConstraints= NO;
[self.view addSubview:redView];
//新增約束
//高度約束
NSLayoutConstraint*hlc = [NSLayoutConstraintconstraintWithItem:redView attribute:NSLayoutAttributeHeightrelatedBy:NSLayoutRelationEqualtoItem:nilattribute:NSLayoutAttributeNotAnAttributemultiplier:0.0constant:100];
[redViewaddConstraint:hlc];
//寬度約束
NSLayoutConstraint*wlc = [NSLayoutConstraintconstraintWithItem:redView attribute:NSLayoutAttributeWidthrelatedBy:NSLayoutRelationEqualtoItem:nilattribute:NSLayoutAttributeNotAnAttributemultiplier:0.0constant:100];
[redViewaddConstraint:wlc];
//右邊間距約束
NSLayoutConstraint*rightlc = [NSLayoutConstraintconstraintWithItem:redView attribute:NSLayoutAttributeRightrelatedBy:NSLayoutRelationEqualtoItem:self.viewattribute:NSLayoutAttributeRightmultiplier:1.0constant:-20];
[self.view addConstraint:rightlc];
//底部間距約束
NSLayoutConstraint*bottomlc = [NSLayoutConstraintconstraintWithItem:redView attribute:NSLayoutAttributeBottomrelatedBy:NSLayoutRelationEqualtoItem:self.viewattribute:NSLayoutAttributeBottommultiplier:1.0constant:-20];
[self.view addConstraint:bottomlc];
複製程式碼
- 另一種是通過xib的方式也有可能會出現這個警告,這是因為view的autoresizingMask屬性引起的
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
複製程式碼
一般情況下,以下這些view的autoresizingMask值預設就是18(UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth
)
1.從xib裡面建立出來的預設控制元件(Xcode自動建立出來的那個view) 2.控制器的view
如果不希望控制元件擁有autoresizingMask的自動伸縮功能,應該設定為none.如果從xib中載入自帶的view出現約束警告,也應該將其設定為none
blueView.autoresizingMask = UIViewAutoresizingNone;
這樣煩人的約束警告就不會再出現了,關於這兩個屬性的詳細解釋,可以檢視下面兩個連結中的兩篇文章.