引言
Masonry在 iOS 開發(fā)界的名氣相信不用多做介紹了, 大部分開發(fā)者在使用Masonry的過程中都會(huì)導(dǎo)入2個(gè)全局的宏來提高開發(fā)效率.
#define MAS_SHORTHAND
#define MAS_SHORTHAND_GLOBALS
這2個(gè)宏有什么作用呢?
#define MAS_SHORTHAND可以讓你在調(diào)用約束方法和設(shè)置約束參數(shù)時(shí)省掉mas_前綴.
[aView mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(bView.mas_right);
make.top.equalTo(bView.mas_bottom).offset(50);
make.width.height.equalTo(@100);
}];
// 加宏后
[aView makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(bView.right);
make.top.equalTo(bView.bottom).offset(50);
make.width.height.equalTo(@100);
}];
而#define MAS_SHORTHAND_GLOBALS也是用來省掉mas_前綴的, 在介紹這個(gè)宏之前我們先來了解一下不加此宏時(shí)最早期的約束寫法.
make.left.equalTo(bView.mas_right);
make.top.equalTo(bView.mas_bottom).offset(50);
make.width.height.equalTo(@100);
可以看出, 在約束數(shù)值時(shí)我們需要包裝成 NSNumber 對(duì)象再傳入. 為了節(jié)省這一包裝操作, 后來加入了mas_前綴的宏, 使得我們可以不用再對(duì)數(shù)值進(jìn)行包裝.
make.left.mas_equalTo(bView.mas_right);
make.top.mas_equalTo(bView.mas_bottom).mas_offset(50);
make.width.height.mas_equalTo(100);
至于offset和mas_offset的區(qū)別沒弄懂...希望有知道的大大可以告訴我一下, 萬分感激. 加入這個(gè)宏雖然節(jié)省了對(duì)數(shù)值進(jìn)行包裝的操作, 不過每次都要敲mas_前綴的宏也是挺麻煩的, 所以最后便有了#define MAS_SHORTHAND_GLOBALS的出現(xiàn), 只要寫上這個(gè)宏, 上面的mas_前綴宏就可以省掉了.
make.left.equalTo(bView.mas_right);
make.top.equalTo(bView.mas_bottom).offset(50);
make.width.height.equalTo(100);
如果2個(gè)宏都寫上的話, 最后代碼就可以寫成這樣了.
[aView makeConstraints:^(MASConstraintMaker *make) {
>
make.left.equalTo(bView.right);
make.top.equalTo(bView.bottom).offset(50);
make.width.height.equalTo(100);
}];
確實(shí)是清爽了許多, 難怪很多人都會(huì)在工程中加入這2個(gè)宏, 但事與愿違, 有時(shí)卻會(huì)造成一些尷尬的情況.
UIView 分類
在開發(fā)中, 我們往往會(huì)為 UIView 寫上一個(gè)分類, 加入width, height, x, y等屬性方便我們使用, 比如說我們拿一個(gè) view 的width屬性需要view.bounds.size.width, 寫上分類后我們只需要view.width就可以了, 非常方便, 那你可能會(huì)問, 這跟Masonry的宏有什么關(guān)系呢?
沖突
還記得第1個(gè)宏#define MAS_SHORTHAND嗎? 今天的主角就是它了, 它可以幫我們把控件的mas_xxx屬性的mas_前綴省掉, 比如我們想要約束 aView 的高度跟 bView 的寬度一樣, 我們會(huì)這樣寫.
make.height.equalTo(bView.width);
那么問題來了, 括號(hào)中width返回的是我們分類中的寬度數(shù)值還是Masonry中的約束對(duì)象呢? 所以就產(chǎn)生沖突了.
編譯是不會(huì)有問題的, 可是只要代碼一運(yùn)行到這一行就會(huì)悲劇了...事實(shí)上只要寫入了這個(gè)宏, 即使不調(diào)用約束的方法, 只是隨便訪問一下控件的width或height屬性, 結(jié)果也一樣.
這里需要說明一下的是, 最新的Masonry已經(jīng)不會(huì)崩了, 不過拿到的也不是我們想要的東西, 比如說獲取控件的width或height屬性值都是0, 而像make.height.equalTo(bView.width);這樣的約束也不起作用...
這就是Masonry宏定義尷尬的地方了, 個(gè)人覺得, 可能還是分類的便捷性更為優(yōu)先, 所以只能犧牲掉這個(gè)宏了. 當(dāng)然你也可以在 UIView 分類所添加的屬性名中加上一個(gè)前綴, 這也是業(yè)界推薦的做法, 用起來麻煩一點(diǎn)就是了.