你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> 關於iOS自動布局

關於iOS自動布局

編輯:IOS開發綜合

這裡做一個通過代碼實現自動布局的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


看完這個類,有必要先說一下我的代碼風格,對於很多剛剛做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方法修改即可,而無需在大量的代碼中搜索那麼幾行代碼.


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

\


閒話到這,繼續主題.


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


\

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

\


接下來就需要對代碼進行一定的調整來完成自動布局.<喎?/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;
}

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

\


  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved