IOS開發之自動布局架構設計(二)

來源:互聯網
上載者:User

標籤:

  【上集劇情概要:上集我們主要剖析了原生的NSLayoutConstraint實現自動布局的方式,我們知道是通過constraintWithItem這個初始化的方法來配備所需要的7個參數,然後通過addConstraint方法將布局添加進去,並且定義了

NSLayoutAttribute,NSLayoutRelation這些枚舉】

如果我們自己設計一款布局架構可以怎麼設計呢?

1.封裝原有的NSLayoutConstraint類,可以將代碼的實現更加簡潔化。例如:Masonry,SDAutoLayout。

2.封裝座標布局,並且實現自有的布局方式,至於用什麼方式展現給使用者,可以自行天馬行空,方便易用就行。

3.使用CSS/XML等方式,將布局檔案放到一個統一的檔案裡面,然後初始化的時候進行載入布局。

4.開發一款軟體,來實現拖拽好布局之後,自動產生代碼,並且有面板可以設定微調當前的參數。

5.還可以將UI動畫封裝到布局裡面,以及控制項的互動的封裝。

好吧,我們來看看如何封裝好NSLayoutConstraint,其實它的核心代碼是:

 1 NSLayoutConstraint *constaintTop = [NSLayoutConstraint 2                                         constraintWithItem:self.tableView 3                                         attribute:NSLayoutAttributeTop 4                                         relatedBy:NSLayoutRelationEqual 5                                         toItem:self.view 6                                         attribute:NSLayoutAttributeTop 7                                         multiplier:1.0 8                                         constant:20]; 9     10     [_tableView addConstraint:constaintTop];

那我們其實就是要封裝這一層代碼,並且實現更好地介面展現給使用者。

1.實現鏈式調用

首先我們寫一個最簡單地實現UI布局的代碼,功能:實現上下左右四個屬性,使用鏈式調用。

如果我們要實現鏈式調用,怎麼實現呢?

IOS中調用方法的實現使用的是【】,只有屬性訪問的時候才用點得方式,那麼可以通過Setter方法嗎?

比如傳回值我們設定為當前的view

@property(nonatomic, readonly) UIView *leftSpace;-(UIView *)leftSpace{    return self;}

那後面的參數怎麼傳給它呢,所以它不能滿足要求。

橘子君又想到一個問題,使用Block呢,因為block作為屬性的時候是可以用這種方式的:

blockLeft(10);

也是可以通過.文法來訪問的比如:

self.blockLeft(10);

那我們怎麼來實現連續的鏈式點文法的操作呢

如果self.blockLeft(10);返回的是self的話,那就可以實現了:

self.blockLeft(10).blockTop(10).blockRight(10).blockBottom(10);

ok, 這樣的話我們可以類比實現一下這種鏈式調用的方式:

#import <UIKit/UIKit.h>@interface UIView (GCFAdditions)@property(nonatomic, readonly) UIView *(^left)(NSInteger space);@property(nonatomic, readonly) UIView *(^right)(NSInteger space);@property(nonatomic, readonly) UIView *(^top)(NSInteger space);@property(nonatomic, readonly) UIView *(^bottom)(NSInteger space);@end

首先簡單類比寫了left,right,top,bottom四個block屬性,傳回值都為self

#import "UIView+GCFAdditions.h"@implementation UIView (GCFAdditions)- (UIView *(^)(NSInteger space))left{    return ^(NSInteger space) {        //code        if (space) {            NSLog(@"%ld",(long)space);        } else {            NSLog(@"%ld",(long)space);        }        return self;    };}- (UIView *(^)(NSInteger space))right{    return ^(NSInteger space) {        //code        if (space) {            NSLog(@"%ld",(long)space);        } else {            NSLog(@"%ld",(long)space);        }                return self;    };}- (UIView *(^)(NSInteger space))top{    return ^(NSInteger space) {        //code        if (space) {            NSLog(@"%ld",(long)space);        } else {            NSLog(@"%ld",(long)space);        }                return self;    };}- (UIView *(^)(NSInteger space))bottom{    return ^(NSInteger space) {        //code        if (space) {            NSLog(@"%ld",(long)space);        } else {            NSLog(@"%ld",(long)space);        }                return self;    };}@end

好,我們來仔細分析下上面的代碼:

首先在屬性裡面聲明一個block,傳回型別為UIView,保證下一步的調用,給了一個參數,測試用的。

然後在實現裡面,返回self,這時候就可以完成鏈式調用

#define SCREEN_WIDTH   [UIScreen mainScreen].bounds.size.width#define SCREEN_HEIGHT  [UIScreen mainScreen].bounds.size.height#import "ViewController.h"#import "Masonry.h"#import "UIView+GCFAdditions.h"@interface ViewController ()<UITableViewDelegate,UITableViewDataSource>@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.        self.tableView.left(50).right(50).top(50).bottom(50);    }- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}-(UITableView *)tableView{    if (!_tableView) {        _tableView=[[UITableView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT)];        _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;        _tableView.backgroundColor=[UIColor redColor];        [self.view addSubview:_tableView];    }    return _tableView;}

列印結果:

2016-09-08 11:22:31.214 TestMansonry[298:16133] 502016-09-08 11:22:31.215 TestMansonry[298:16133] 502016-09-08 11:22:31.216 TestMansonry[298:16133] 502016-09-08 11:22:31.216 TestMansonry[298:16133] 50

 

2.實現最簡單的布局

 

 

上面我們實現了鏈式調用,那麼我們如何運用它來實現布局呢,請看如下代碼:

 NSLayoutConstraint *constaintRight = [NSLayoutConstraint                                             constraintWithItem:self                                             attribute:NSLayoutAttributeRight                                             relatedBy:NSLayoutRelationEqual                                             toItem:self.superview                                             attribute:NSLayoutAttributeRight                                             multiplier:1.0                                             constant:-space];        [self.superview addConstraint:constaintRight];

 

我們知道實現布局的核心代碼是這一段,我們直接移到之前的分類裡面就會實現這種效果

- (UIView *(^)(NSInteger space))left{    return ^(NSInteger space) {        if (space) {            NSLog(@"%ld",(long)space);        } else {            NSLog(@"%ld",(long)space);        }                NSLayoutConstraint *constaintLeft = [NSLayoutConstraint                                            constraintWithItem:self                                            attribute:NSLayoutAttributeLeft                                            relatedBy:NSLayoutRelationEqual                                            toItem:self.superview                                            attribute:NSLayoutAttributeLeft                                            multiplier:1.0                                            constant:space];                [self.superview addConstraint:constaintLeft];                return self;    };}

 

在實現裡面加入

self.tableView.left(50).right(50).top(50).bottom(50);

就可以實現上下左右各50的間距了,哈哈!

 

IOS開發之自動布局架構設計(二)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.