關於iOS自動布局

來源:互聯網
上載者:User

這裡做一個通過代碼實現自動布局的Demo,通過IB來做的就不講了,網上相關的資料很多,這裡給出一個寫的不錯的連結,有興趣的同學自己看吧.

iOS7自動布局教程(一)

iOS7自動布局教程(二) --英文


要談自動布局,那基本的視圖是第一步,做了一個這樣的ViewController

////  NESMainViewController.m//  AutoLayout////  Created by Nestor on 14-3-2.//  Copyright (c) 2014年 NesTalk. All rights reserved.//#import "NESMainViewController.h"@interface NESMainViewController ()@property (nonatomic,retain) UIView *view1;@property (nonatomic,retain) UIView *view2;@property (nonatomic,retain) UIView *view3;@end@implementation NESMainViewController-(UIView *)view1{    if (!_view1) {        _view1 = [[UIView alloc] initWithFrame:CGRectMake(10, 30, 145, 200)];        _view1.backgroundColor = [UIColor greenColor];    }    return _view1;}-(UIView *)view2{    if (!_view2) {        _view2 = [[UIView alloc] initWithFrame:CGRectMake(165, 30, 145, 200)];        _view2.backgroundColor = [UIColor yellowColor];    }    return _view2;}-(UIView *)view3{    if (!_view3) {        _view3 = [[UIView alloc] initWithFrame:CGRectMake(10, 240, 300, 300)];        _view3.backgroundColor = [UIColor blueColor];    }    return _view3;}-(void)buildLayout{    [self.view addSubview:self.view1];    [self.view addSubview:self.view2];    [self.view addSubview:self.view3];}- (void)viewDidLoad{    [super viewDidLoad];    [self buildLayout];}- (void)didReceiveMemoryWarning{    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}@end


看完這個類,有必要先說一下My Code風格,對於很多剛剛做iOS開發不久的程式員看這部分代碼可能感覺很麻煩~但是按照這種風格進行編碼是有很大好處的.

先看這段代碼

-(UIView *)view1{    if (!_view1) {        _view1 = [[UIView alloc] initWithFrame:CGRectMake(10, 30, 145, 200)];        _view1.backgroundColor = [UIColor greenColor];    }    return _view1;}


這段代碼的寫法經常能夠看到,單例裡面有他,TableView的代理方法能用到他,這裡屬於重寫@property的getter方法,簡單來說,通過點文法來調用私人成員變數:self.view1來調用該方法,有兩大好處

1.分離了不同方法的構造內容,代碼層次更加明顯.

2.消極式載入,什麼時候需要什麼時候建立,而不是統一在ViewDidLoad方法中進行建立,對於複雜的視圖控制器來說可以最佳化運行效率.


再看ViewDidLoad方法裡

- (void)viewDidLoad{    [super viewDidLoad];    [self buildLayout];}

非常簡單,調用了一個buildLayout方法,看方法名就能夠知道,這裡是專門用來初始化視圖布局的方法,由於在oc中init開頭的方法被看做類的初始化方法,故此使用了build,當然這屬於個人習慣,無所謂的事~


buildLayout方法則逐個將要添加的控制項放到了view上

-(void)buildLayout{    [self.view addSubview:self.view1];    [self.view addSubview:self.view2];    [self.view addSubview:self.view3];}

這裡就能夠明顯的看到通過重寫getter方法來初始化視圖的好處了,都添加了哪些控制項一目瞭然,如果需要修改某一個控制項,那直接定位到對應的getter方法修改即可,而無需在大量的代碼中搜尋那麼幾行代碼.


根據這樣的代碼布局進行編寫,對於單一視圖控制器來說,就可以有了這樣的分層效果:



閑話到這,繼續主題.


代碼到這裡螢幕上的視圖應該如所示



是我們需要的布局效果,但是如果螢幕橫過來,問題就出現了



接下來就需要對代碼進行一定的調整來完成自動布局.<喎?http://www.bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+tNNpT1M2v6rKvC4uLtOmuMPKx9XiyrG68r+qyrywySzP67K7xvDAtMHLLLzTyOvBy05TTGF5b3V0Q29uc3RyYWludCzV4rj2vs3Kx9f219S2r7K8vtbQ6NKq08O1vbXEtqvO9zwvcD4KPHA+PGJyPgo8L3A+CjxwPtTayrnTw05TTGF5b3V0Q29uc3RyYWludLXEyrG68tDo0qrTw7W90rvW1lZpc3VhbCBGb3JtYXQgTGFuZ3VhZ2UssrvKx8zYsfDE0bXEtqvO9yyxvs7EtcREZW1vwO+74bzytaW96cncLLj8ye6y47XEtqvO99PQ0MvIpNfUvLrL0cv30rvPwrDJLjwvcD4KPHA+PGJyPgo8L3A+CjxwPsrXz8jQ6NKq1No8L3A+CjxwPjwvcD4KPHByZSBjbGFzcz0="brush:java;">-(UIView *)view1{ if (!_view1) { _view1 = [[UIView alloc] initWithFrame:CGRectMake(10, 30, 145, 200)]; _view1.backgroundColor = [UIColor greenColor]; } return _view1;}以及其他方法中添加如下代碼:

        _view1.translatesAutoresizingMaskIntoConstraints = NO;
用來禁止AutoresizingMask轉換成AutoLayout,簡單來說,Autoresizing和AutoLayout用的不是一套東西,但是預設情況下是相互轉換的,這裡我們要指定使用AutoLayout系統,所以要禁止自動轉換


跟著在buildLayout方法中添加下列內容:

    NSDictionary *views = NSDictionaryOfVariableBindings(self.view,_view3,_view2,_view1);        [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[_view1(==_view2)]-10-[_view2]-10-|" options:0 metrics:0 views:views]];    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-30-[_view1(<=200)]-10-[_view3]-10-|" options:0 metrics:0 views:views]];    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-30-[_view2(<=200)]-10-[_view3]-10-|" options:0 metrics:0 views:views]];    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[_view3]-10-|" options:0 metrics:0 views:views]];    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[_view3(>=150)]-10-|" options:0 metrics:0 views:views]];

一步一步看:

    NSDictionary *views = NSDictionaryOfVariableBindings(self.view,_view3,_view2,_view1);
這裡用到了一個系統宏定義,NSDictionaryOfVariableBindings(),其作用是產生一個詞典,key的名字和對象的標識符相同,以上述為例,產生的詞典形式就是{"self.view":self.view,@"_view3":_view3,...},這個詞典應當包含需要自動布局的父視圖和所有的子視圖,

    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[_view1(==_view2)]-10-[_view2]-10-|" options:0 metrics:0 views:views]];
這裡則是添加了一條自動布局規則,可以看到有個比較麻煩的字串參數,簡單解釋一下

| 螢幕的邊框

-10- 10個點的間距

[_view2] 需要布局的控制項,這裡的_view2必須和上邊用來產生詞典的標識符完全相同

[_view1(==_view2)] _view1的作用和上邊完全相同,而()裡面的則是限定條件,可以是==某一個空間,或者一個固定的數值,當然,除了==之外還可以使用>=或者<=;


字串中的每個部分都解釋清楚後,那麼就容易理解多了~這句話完整的意思整理出來就是:

兩個寬度相同的view,其間距是10個點,距離左右邊框的距離也是10個點~


這樣,無論是豎屏還是橫屏,都會按照這樣一個標準來去進行自動布局.


值得注意的是,能夠執行這種布局的view必須通過-(CGSize)intrinsicContentSize方法返回一個有效CGSize,而UIView預設返回的是0,所以如果只設定了橫向的布局規則那麼UIView是不會顯示在螢幕上的

對於UIView而言,必須同時設定橫向和縱向布局規則或者寫一個繼承自UIView的自訂View然後重寫-(CGSize)intrinsicContentSize才能實現該效果.

但是對於UIButton,UILabel等則不必,設定個橫向的就夠了.


再看下一句:

V:|-30-[_view1(<=200)]-10-[_view3]-10-|

V: 代表的是垂直方向上的布局規則

簡單解釋一下,view1的高度不能大於200點,距離上邊框30個點,與view3的間距是10個點,view3與底邊框的距離是10個點

由此,通過設定view1的高度上限和間距就可以自動計算出view3的高度.其他的布局規則大家自己看一下也就可以明白了.

同時,如果規定了全部子視圖的布局規則,那麼也就沒有必要去設定子視圖的frame了.各個frame的初始化方法可以改寫成:

-(UIView *)view1{    if (!_view1) {        _view1 = [[UIView alloc] init];        _view1.backgroundColor = [UIColor greenColor];        _view1.translatesAutoresizingMaskIntoConstraints = NO;    }    return _view1;}

由此便完成了整個視圖的自動布局,還是非常容易實現的,就個人而言,通過代碼來進行自動布局比xib要方便的多.大家可以自行選擇.


如果在view1中需要添加子view同樣需要自動布局呢?看看下列代碼,非常簡單:

-(UIView *)view1{    if (!_view1) {        _view1 = [[UIView alloc] init];        _view1.backgroundColor = [UIColor greenColor];        _view1.translatesAutoresizingMaskIntoConstraints = NO;                UIView *view = [[UIView alloc] init];        view.backgroundColor = [UIColor magentaColor];        [_view1 addSubview:view];        view.translatesAutoresizingMaskIntoConstraints = NO;        NSDictionary *views = NSDictionaryOfVariableBindings(_view1,view);        [_view1 addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-10-[view]-10-|" options:0 metrics:0 views:views]];        [_view1 addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-10-[view]-10-|" options:0 metrics:0 views:views]];            }    return _view1;}

好了,到這裡自動布局就差不多了,如下:



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.