【iOS學習筆記 15-12-3】關於masonry佈局中的frame和bounds

iPhone每年更新一款新的產品,屏幕也開始出現碎片化問題。所以在iPhone開發上面也碰到了和安卓一樣不可避免的問題,就是不同屏幕的適配。

這些在面試中,也有面試官問到過,之前一直在忙着找工作的事,雖然autolayout出來了很久,但是一直沒時間去研究。因爲自己入門的時候就是學的代碼佈局,包括storyboard、xib用的比較少。

其實我現在代碼佈局要適配4,4s,5,6,6p感覺已經是強弩之末了,如果再出7的話真的要頭疼了抓狂。而且我的步伐慢了,好多同行前輩都已經把autolayout研究的爛熟了,所以最近下決心要學一下autolayout,直接上手masonry。由於簡書上面有很多比較好的教程,直接站在巨人的肩膀上研究這個。

感覺和之前使用的代碼佈局比較相似,於是很順利的把項目中的一個界面換成了masonry佈局。

但是在轉換的過程中,發現UIView設置圓角的時候出現問題了,原始代碼如下,img在APP中不顯示。後來把貝塞爾曲線那一段註釋掉,發現圖片可以顯示了,但是左上角和右上角的圓角沒了。

//        UIImageView *img = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, imgwidth, imgheight)];
        UIImageView *img = [UIImageView new];
        [view addSubview:img];
        [img mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(0);
            make.left.mas_equalTo(0);
            make.width.mas_equalTo(imgwidth);
            make.height.mas_equalTo(imgheight);
        }];
        NSString *imgStr = [NSString stringWithFormat:@"http://www.baidu.com%@",[dic objectForKey:@"coverImage"]];//此處url是隨便的一個網址
        NSURL *url = [NSURL URLWithString:imgStr];
        [img sd_setImageWithURL:url placeholderImage:nil];
        
        img.backgroundColor = [UIColor redColor];
        UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:img.bounds byRoundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight cornerRadii:CGSizeMake(5, 5)];
        CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
        maskLayer.frame = CGRectMake(0, 0, imgwidth, imgheight);
        maskLayer.path = maskPath.CGPath;
        img.layer.mask = maskLayer;
在網上查了很多資料,但是很少有介紹爲什麼在使用masonry之後控件的frame和bounds都是爲0

後來翻倒一篇文章,才發現,其實對於masonry的理解不夠深http://www.cocoachina.com/ios/20141010/9869.html

其實我還是沒有擺脫傳統代碼裏面的frame的影響,基於autolayout的masonry控制的空間佈局不再取決於手動直接修改,而且是通過在storyboard或者code中提供的約束條件,通過一個自動佈局引擎來實現的(見鏈接文章)。

當設置完控件的約束,需要調用layoutIfNeeded 函數進行佈局,然後所約束的控件纔會按照約束條件,生成當前佈局相應的frame和bounds。這樣就可以利用這兩個屬性來進行圖片圓角剪裁。


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

  • setNeedsLayout:告知頁面需要更新,但是不會立刻開始更新。執行後會立刻調用layoutSubviews。
  • layoutIfNeeded:告知頁面佈局立刻更新。所以一般都會和setNeedsLayout一起使用。如果希望立刻生成新的frame需要調用此方法,利用這點一般佈局動畫可以在更新佈局後直接使用這個方法讓動畫生效。
  • layoutSubviews:系統重寫佈局
  • setNeedsUpdateConstraints:告知需要更新約束,但是不會立刻開始
  • updateConstraintsIfNeeded:告知立刻更新約束
  • updateConstraints:系統更新約束
具體細節可以參考:

AutoLayOut框架Masonry使用心得



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章