Masonry框架初次使用遇到的坑 frame爲0

 

實現自適應佈局的一個很是方便的方法就是使用Masonry框架,然而使用Masonry佈局的時候,並不能馬上反應到frame的改變上,好比:ios

UIView *parent = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; UIImageView *child = [UIView alloc] init]; [parent addSubview:child]; [child mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(20,20)); make.top.left.mas_equalTo(50); }]; NSLog(@"%@",redView); 打印結果: ** <UIImageView: 0x7fb222605550; frame = (0 0; 0 0); layer = <CALayer: 0x7fb22260b3a0>>**

能夠發現,雖然使用Masonry進行佈局和約束,可是子視圖childframe仍然爲(0, 0, 0 ,0). 框架

而這時候若是有需求要設置child的形狀爲圓形,就得知道它的frame,像下面這樣寫確定不會設置成功的:異步

[child mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(20,20)); make.top.left.mas_equalTo(50); }]; child.layer.cornerRadius = child.bounds.size.width/2; child.layer.masksToBounds = YES; //設置頭像爲圓形

由於這時候的frame仍是0。我想會不會是由於block中的處理是放在另外一個線程中異步進行的,block還沒執行完就已經走到了下面使用frame的代碼,(一陣狂喜,好聰明。。。),因此立刻把代碼改寫:函數

[child mas_makeConstraints:^(MASConstraintMaker *make) { make.size.mas_equalTo(CGSizeMake(20,20)); make.top.left.mas_equalTo(50); child.layer.cornerRadius = child.bounds.size.width/2; child.layer.masksToBounds = YES; //設置頭像爲圓形 }];

然而並無什麼卵用。。。佈局

沒辦法只能問谷歌了,而後找到了Masonry約束下獲取frame的方法:動畫

使用masonry的實質仍是調用了ios7之後的autolayout,若是要更新frame,須要調用layoutIfNeeded函數進行佈局,而後所約束的控件纔會按照約束條件,生成當前佈局相應的framebounds。這樣就能夠利用這兩個屬性來進行圖片圓角剪裁。而調用layoutIfNeeded的目的是讓系統調用layoutSubviews方法,咱們也能夠直接在這個方法裏獲取frame,由於這時候開始layout subviews,Masonry已經計算出了真實的frame。ui

下面附上關於autolayout更新幾個方法的區別:spa

setNeedsLayout:告知頁面須要更新,可是不會馬上開始更新。執行後會馬上調用layoutSubviews。線程

layoutIfNeeded:告知頁面佈局馬上更新。因此通常都會和setNeedsLayout一塊兒使用。若是但願馬上生成新的frame須要調用此方法,利用這點,動畫能夠在更新佈局後直接使用這個方法讓動畫生效。code

layoutSubviews:系統重寫佈局

setNeedsUpdateConstraints:告知須要更新約束,可是不會馬上開始

updateConstraintsIfNeeded:告知馬上更新約束

updateConstraints:系統更新約束

相關文章
相關標籤/搜索