標籤:
1. stroyBoard右下角4個按鈕的用途
從左至右,第1個按鈕,是添加對齊約束的;
第2個按鈕,是添加標準約束的;
第3個按鈕,可以讓Xcode自動產生約束或者更新視圖到正確位置;
第4個按鈕,可以設定讓哪些類繼承這些約束,預設情況下,2個選項都是選中的,建議把Silbings和Ancestors留空,如果選中的話,對齊視圖中的子視圖會變得很困難
2. 固有尺寸
添加約束時,要注意,某些控制項有固有尺寸,像分段選取器,滑塊,進度條,進度列指示器,laibel都有固有尺寸.
可以看到滑塊的高度是置灰的。這就是固有尺寸啦。
label的固有尺寸比較特殊,由常值內容決定自己的寬度。
3. 線框代表的含義
3.1 對控制項添加完約束之後,正確的情況應該是分段選取器這樣(圖1)。
3.1 如果約束存在歧義,則是label那樣(圖2),有黃色線框和紅色線段:黃色實線框表示當前設計時的位置和尺寸,label頂部的紅色線段表示,上邊距存在歧義,底部的紅色線段表示,下邊距存在歧義。
3.3 繼續給label添加約束,直至歧義全部消失。會變成圖3的樣子,有黃色實線框和紅色虛線框,黃色實線框的含義依然是當前設計時的位置和尺寸;紅色虛線框,表示程式運行時,label的位置和尺寸。
3.4 通過update frame,可以讓storyboard上Label控制項完全按自動布局的設定更新一遍,這樣可以使紅色虛線框消失,變成圖4那樣,圖4的+28含義,表示程式允許時和底部進度條間距會多出28點,此時可以通過update constraints,讓約束條件迎合當前stroyboard顯示的間距,更新完之後,約束條件裡的40變成68,見圖6
3.5 但是一般不會這麼做,因為約束一般情況下是沒問題,應該是更新frame,讓frame去適應我們設定的約束,點擊fix misplacement,修複錯位,見圖7
圖1
圖2
圖3
圖4
圖5
圖6
圖7
4. 頂部和底部布局引導
iOS7之後,控制器具有topLayoutGuide,bottomLayoutGuide這2個屬性,在Xcode5以上版本中,storyboard中可以看到這2個東西。
@interface UIViewController (UILayoutSupport)
// These objects may be used as layout items in the NSLayoutConstraint API
@property(nonatomic,readonly,retain) id<UILayoutSupport> topLayoutGuide NS_AVAILABLE_IOS(7_0);
@property(nonatomic,readonly,retain) id<UILayoutSupport> bottomLayoutGuide NS_AVAILABLE_IOS(7_0);
@end
在給控制項添加頂部約束時,可以選擇距離Top Layout Guide,這麼做的好處是,即使存在狀態列,導覽列的情況下,Top Layout Guide會包含這些xx欄的高度,如果應用要同時允許在iOS6,iOS7中運行,那麼這種好處就更明顯了。
5. 怎麼對滾動視圖做自動布局
http://blog.csdn.net/dongtaochen2039/article/details/41749209
6. 自動布局和setFrame
使用自動布局的控制項,即使對控制項setFrame,也不會有效果,因為自動布局擁有決定權
7. 用代碼實現自動布局7.1 向視圖中添加約束
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeContactAdd];
[btn1 setTranslatesAutoresizingMaskIntoConstraints:NO]; // 自動布局和autoresizing是互斥的,所以使用自動布局之前,一定要把autoresizing取消
UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeContactAdd];
[btn2 setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:btn1]; // 在添加約束之前,一定要先把子視圖添加到父視圖上。說白了addSubview必須寫在addConstraint前面。
[self.view addSubview:btn2]; // 如果先添加約束,再把子視圖添加到父視圖上,程式會崩潰。
NSLayoutConstraint *layout = [NSLayoutConstraint constraintWithItem:btn1 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:50]; // 代表的含義:btn1的centerY = self.view的頂部y值 * multipler(係數) + constant(常數)
NSLayoutConstraint *layout1 = [NSLayoutConstraint constraintWithItem:btn1 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:200];
NSLayoutConstraint *layout2 = [NSLayoutConstraint constraintWithItem:btn2 attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:btn1 attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:100];
NSLayoutConstraint *layout3 = [NSLayoutConstraint constraintWithItem:btn2 attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:btn1 attribute:NSLayoutAttributeTop multiplier:1.0 constant:50];
[self.view addConstraint:layout];
[self.view addConstraint:layout1];
[self.view addConstraint:layout2];
[self.view addConstraint:layout3];
}
7.2 使用可視格式化語言(VFL)添加約束
- (void)viewDidLoad {
[super viewDidLoad];
UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeContactAdd];
[btn1 setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.view addSubview:btn1];
NSDictionary *viewsDic = NSDictionaryOfVariableBindings(btn1);
NSArray *constraints1 = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[btn1]" options:0 metrics:nil views:viewsDic];
NSArray *constraints2 = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-100-[btn1]" options:0 metrics:nil views:viewsDic];
[self.view addConstraints:constraints1];
[self.view addConstraints:constraints2];
}
無論是給視圖添加約束,還是用可視格式化語言,都太繁瑣了,還是藉助第3方架構吧,例如UIView+AutoLayout
iOS 自動布局