iOS開發-UI篇-AutoLayout

1.概述:隨着iOS設備的更新迭代,屏幕適配問題也變得愈發重要,應運而生了Autolayout。在Xcode4.1OS X10.7以後才起效。api

2.簡介:Apple提供了2種方式佈局Autolayout,xib來佈局;另外一種利用代碼進行佈局,Applesdk中提供了2個類庫:NSLayoutManagerNSLayoutConstraintNSLayoutManager類主要是配合NSTextStorage,NSTextContainer實現NSCoding協議用來佈局text視圖,NSLayoutConstraint類則是佈局整個視圖結構(着重介紹)數組

3.原理:Autolayout的主要思想就是約束。在NSLayoutConstraint類中,有一個最重要的類方法xcode

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

實現的公式是"view1.attr1 = view2.attr2 * multiplier + constant".創建2個視圖之間的約束聯繫(第二視圖能夠爲nil)。可是用這個方法的簡單明瞭,缺點就是太過繁瑣複雜.可是咱們推薦使用VFL進行佈局。ide

4.1內容:佈局

1).當咱們使用Autolayout,咱們要摒棄Xcode自動適應設置,translatesAutoresizingMaskIntoConstraintsNO;否則會形成視圖混亂。spa

2).聽從高內聚的原則,UIView.h類中系統定義了- (void)updateConstraints;UIViewController.h類中系統定義了- (void)updateViewConstraints;Overrides must call super or send -updateConstraints to the view=>[super updateViewConstraints];code

3).最基本的添加約束的方法:建立一個view對象,建立一個NSLayoutConstraint約束對象,constraintWithItem進行約束設置,view對象中添加約束。orm

4.2內容:對象

1).Autolayout還提供了VFL(Visual Format Language)來約束,+ (NSArray *)constraintsWithVisualFormat:(NSString *)format options:(NSLayoutFormatOptions)opts metrics:(NSDictionary *)metrics views:(NSDictionary *)views;blog

//format:傳入單獨每一個view的約束語句;查詢xcodeapiVisual Format Syntax

2).Autolayout步驟:建立一個view,而且添加到父視圖中去顯示->[父視圖 addConstraints:(約束數組)]->傳入參數,format具體約束語句,opts可置爲nil,metrics傳入距離參數(用參數代替魔數),views傳入相應的視圖控件,metricsviews是爲format服務的。

3).1:

- (void)updateViewConstraints{
    [super updateViewConstraints];//override初始化
    
    UIView *view1 = [[UIView alloc] init];
    view1.translatesAutoresizingMaskIntoConstraints = NO;//取消自動佈局
    view1.backgroundColor = [UIColor blueColor];
    [self.view addSubview:view1];
    
    NSDictionary *views_Dic = @{@"view1":view1};//約束的控件
    
    NSString *hLayoutStr = @"H:|-(==100)-[view1(==100)]";//H:表明橫向,|表明相對於父視圖,-表明約束距離,()裏面的全部表示約束距離,[]裏面表示約束的視圖對象,這句話表示:橫向從左到右,相對於父視圖距離100像素,view1的寬爲100
    NSString *vLayoutStr = @"V:|-(==100)-[view1(==50)]";//V:表明縱向,|表明相對於父視圖,-表明約束距離,()裏面的全部表示約束距離,[]裏面表示約束的視圖對象,這句話表示:縱向從上到下,相對於父視圖距離100像素,view1的高爲50
    
    NSArray *hLayoutArr =  [NSLayoutConstraint constraintsWithVisualFormat:hLayoutStr options:0 metrics:nil views:views_Dic];
    NSArray *vLayoutArr =  [NSLayoutConstraint constraintsWithVisualFormat:vLayoutStr options:0 metrics:nil views:views_Dic];
    [self.view addConstraints:hLayoutArr];
    [self.view addConstraints:vLayoutArr];
}

2:

- (void)updateViewConstraints{
    [super updateViewConstraints];//override初始化
    
    UIView *view1 = [[UIView alloc] init];
    view1.translatesAutoresizingMaskIntoConstraints = NO;
    view1.backgroundColor = [UIColor blueColor];
    [self.view addSubview:view1];
    
    UIView *view2 = [[UIView alloc] init];
    view2.translatesAutoresizingMaskIntoConstraints = NO;
    view2.backgroundColor = [UIColor greenColor];
    [self.view addSubview:view2];
    
    NSDictionary *views_Dic = @{@"view1":view1,@"view2":view2};
    NSDictionary *views_metrics = @{@"Top":@50,@"Right":@20};
    
    NSString *hLayoutStr = @"H:|-(==100)-[view1(==100)]-[view2(view1)]-Right-|";//表示:從父視圖的左邊開始,約束100像素,約束view1的寬爲100像素,約束view2的寬與view1等寬,約束距離父視圖右邊的距離爲20像素。
    NSString *vLayoutStr = @"V:|-(100)-[view1(==100)]-[view2(==100)]";
    
    
    NSArray *hLayoutArr =  [NSLayoutConstraint constraintsWithVisualFormat:hLayoutStr options:0 metrics:views_metrics views:views_Dic];
    NSArray *vLayoutArr =  [NSLayoutConstraint constraintsWithVisualFormat:vLayoutStr options:0 metrics:views_metrics views:views_Dic];
    [self.view addConstraints:hLayoutArr];//橫向約束
    [self.view addConstraints:vLayoutArr];//縱向約束
}

 例3:

- (void)viewDidLoad {
UIView *view_nav = [[UIView alloc] init];
view_nav.translatesAutoresizingMaskIntoConstraints = NO;
view_nav.backgroundColor = [UIColorFactory colorNav];
[self.view addSubview:view_nav];

self.mUAccounts_table = [[UITableView alloc] init];
self.mUAccounts_table.delegate = self;
self.mUAccounts_table.dataSource = self;
self.mUAccounts_table.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.mUAccounts_table];

//AutoLayout進行約束
NSDictionary *views_dic = @{@"view_nav":view_nav,@"mUAccounts_table":self.mUAccounts_table};
NSDictionary *metrics_dic = @{@"Top":@0,@"Bottom":@0,@"Left":@0,@"Right":@0,
                              @"ScreenWidth":@((float)ScreenWidth),
                              @"tabBar_height":@(self.tabBarController.tabBar.frame.size.height),
                              @"Table_height":@((float)ScreenHeight-64-49)};
//當等寬或者等高時,將相同方向的兩個視圖拆分紅同個方向的2個約束
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-Left-[view_nav(ScreenWidth)]" options:NSLayoutFormatAlignAllLeft metrics:metrics_dic views:views_dic]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-Top-[view_nav(64)]-[mUAccounts_table(Table_height)]" options:0 metrics:metrics_dic views:views_dic]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[mUAccounts_table(ScreenWidth)]" options:0 metrics:metrics_dic views:views_dic]];
}

 

5.1注意:

1).有可能出現-(void)updateViewConstraints;不自動調用的狀況,能夠直接在viewDidLoad中添加[self updateViewConstraints];進行調用。

2).VFL的結構1:-距離-對象(尺寸)-距離,不能出現-距離-距離的狀況。

3).當出現Unable to simultaneously satisfy constraints時意味着約束之間有衝突,不能知足全部約束。

4).限定一個視圖的約束通常經過與其餘視圖的位置和自身寬高總共4個約束,或者所有與其餘視圖約束,自身不作寬高約束。(4個約束靈活造成一個適配的視圖)

5).約束對象注意,父視圖添加約束,自身寬高約束則是自身當作父視圖來約束。

6).當出現等寬和等高的狀況時,可將同一個方向的兩個視圖約束拆分紅同個方向的2個約束。

相關文章
相關標籤/搜索