iOS 裁剪View指定的某幾個(gè)角為圓角以及遇到的問(wèn)題

最近遇到一個(gè)需求犬耻,label樣式設(shè)置如下,并不是四個(gè)圓角执泰,而是右上和右下設(shè)置圓角枕磁。

指定裁剪圓角

代碼很簡(jiǎn)單,寫(xiě)一個(gè)方法术吝,需要裁剪的控件調(diào)用以下方法即可计济。

-(void)changeLabelStyle:(UILabel *)label{
UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:label.bounds byRoundingCorners:UIRectCornerTopRight | UIRectCornerBottomRight cornerRadii:CGSizeMake(20, 20)];
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
maskLayer.frame = label.bounds;
maskLayer.path = maskPath.CGPath;
label.layer.mask = maskLayer;
}
  • (instancetype)bezierPathWithRoundedRect:(CGRect)rect byRoundingCorners:(UIRectCorner)corners cornerRadii:(CGSize)cornerRadii;在這個(gè)方法中,第二個(gè)參數(shù)UIRectCorner是一個(gè)枚舉類型排苍,即你需要指定裁剪為圓角的view的角沦寂。
typedef NS_OPTIONS(NSUInteger, UIRectCorner) {
UIRectCornerTopLeft     = 1 << 0,  //左上角
UIRectCornerTopRight    = 1 << 1, //右上角
UIRectCornerBottomLeft  = 1 << 2, //左下角
UIRectCornerBottomRight = 1 << 3, //右下角
UIRectCornerAllCorners  = ~0UL   //四個(gè)角
};

如果你想裁剪多個(gè)不同的角,可以用"|"進(jìn)行組合淘衙,傳入多個(gè)即可传藏。方法中的CAShapeLayer是一個(gè)神奇的子類,可以定制很多有趣的UI控件,具體可以參考簡(jiǎn)書(shū)里的這篇文章放肆的使用UIBezierPath和CAShapeLayer畫(huà)各種圖形


從結(jié)果來(lái)看符合要求毯侦,但是這篇文章的重點(diǎn)不在這西壮,而是我下面要說(shuō)的事情,也是我實(shí)現(xiàn)這個(gè)需求過(guò)程中遇到的問(wèn)題叫惊,記錄一下款青。

這個(gè)需求是要在兩個(gè)頁(yè)面實(shí)現(xiàn)的,方法和調(diào)用都一致霍狰。只是這兩個(gè)頁(yè)面的我創(chuàng)建label的方式不一樣抡草,這也才導(dǎo)致了問(wèn)題的發(fā)生。第一個(gè)頁(yè)面的我是用xib拖的label蔗坯。第二個(gè)頁(yè)面我是用純代碼創(chuàng)建的label康震。下面就分兩種情況具體說(shuō)一下。

xib創(chuàng)建的label

這種情形下很簡(jiǎn)單宾濒,我在xib相關(guān)聯(lián)的.m文件中awakeFromNib方法中調(diào)用方法即可腿短,運(yùn)行結(jié)果也正常。

- (void)awakeFromNib {
[super awakeFromNib];
// Initialization code
[self changeLabelStyle:self.pic_tag_label1];
[self changeLabelStyle:self.pic_tag_label2];
[self changeLabelStyle:self.pic_tag_label3];
}
xib運(yùn)行結(jié)果

但是第二個(gè)頁(yè)面用純代碼創(chuàng)建的label就出了問(wèn)題了绘梦。

純代碼創(chuàng)建的label

ps:因?yàn)楫?dāng)時(shí)是在項(xiàng)目工程中發(fā)現(xiàn)的問(wèn)題橘忱,已經(jīng)解決上傳了,所以我后來(lái)寫(xiě)了個(gè)簡(jiǎn)單的demo卸奉,效果跟我預(yù)期的差不多钝诚。

代碼如下,是創(chuàng)建一個(gè)tableview榄棵,自定義headerview凝颇,以下是自定義headerview代碼。
- (UIView *)creatHeaderView{

UIView *topView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 240)];

UILabel *label = [[UILabel alloc]init];
label.backgroundColor = [UIColor redColor];
label.text = @"圓角測(cè)試";
label.textAlignment = NSTextAlignmentCenter;
[topView addSubview:label];

[label mas_makeConstraints:^(MASConstraintMaker *make) {
   
    make.size.mas_equalTo(CGSizeMake(100, 40));
    make.leading.equalTo(topView.mas_leading).offset(100);
    make.top.equalTo(topView.mas_top).offset(100);
    
}];

[self changeLabelStyle:label];

return  topView;

}

運(yùn)行結(jié)果

label不能正常顯示疹鳄,接著切換3D視圖查看拧略。

3D視圖

再打印label的信息,控制臺(tái)顯示如下

Printing description of $3:
<UILabel: 0x7f83fc413740; frame = (100 100; 100 40); text = '圓角測(cè)試';       userInteractionEnabled = NO; layer = <_UILabelLayer: 0x6080002877b0>>
(lldb) 

label其實(shí)是存在的瘪弓,但是不能顯示垫蛆,自然就聯(lián)想到了調(diào)用裁剪圓角的方法,肯定是這里出了問(wèn)題杠茬,在這個(gè)方法里月褥,傳進(jìn)的是label控件弛随,涉及到label的frame瓢喉,所以我就打印了一下label的frame,結(jié)果如下

打印label結(jié)果

再回過(guò)頭來(lái)看上面的代碼舀透,我是用masonry設(shè)置完label的約束之后調(diào)用的方法栓票,我在想,是不是masonry設(shè)置約束block中的處理是放在另一個(gè)線程中異步進(jìn)行的,block還沒(méi)執(zhí)行完就已經(jīng)走到了下面使用frame的代碼走贪,所以把方法的調(diào)用寫(xiě)在了設(shè)置約束的block里佛猛,但是label依然不能正常顯示,label的frame打印結(jié)果依舊是上面的結(jié)果坠狡。

后來(lái)和朋友說(shuō)了這事继找,自己也在網(wǎng)上查了資料,才發(fā)現(xiàn):
使用masonry的實(shí)質(zhì)還是調(diào)用了ios7以后的autolayout逃沿,如果要更新frame婴渡,需要調(diào)用layoutIfNeeded函數(shù)進(jìn)行布局,然后所約束的控件才會(huì)按照約束條件凯亮,生成當(dāng)前布局相應(yīng)的frame和bounds边臼。這樣就可以利用這兩個(gè)屬性來(lái)進(jìn)行圖片圓角剪裁。而調(diào)用layoutIfNeeded的目的是讓系統(tǒng)調(diào)用layoutSubviews方法假消,我們也可以直接在這個(gè)方法里獲取frame柠并,因?yàn)檫@時(shí)候開(kāi)始layout subviews,Masonry已經(jīng)計(jì)算出了真實(shí)的frame富拗。

最后我在調(diào)用裁剪圓角方法的前面調(diào)用了layoutIfNeeded方法臼予,label成功顯示,此時(shí)打印label的frame也是正確的啃沪。

- (UIView *)creatHeaderView{

UIView *topView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, 240)];
UILabel *label = [[UILabel alloc]init];
label.backgroundColor = [UIColor redColor];
label.text = @"圓角測(cè)試";
label.textAlignment = NSTextAlignmentCenter;
[topView addSubview:label];
[label mas_makeConstraints:^(MASConstraintMaker *make) {
    make.size.mas_equalTo(CGSizeMake(100, 40));
    make.leading.equalTo(topView.mas_leading).offset(100);
    make.top.equalTo(topView.mas_top).offset(100);
}];
[label layoutIfNeeded];
[self changeLabelStyle:label];

return  topView;
}

label正常顯示
此時(shí)label打印結(jié)果

附上關(guān)于autolayout更新幾個(gè)方法的區(qū)別:

  • setNeedsLayout:告知頁(yè)面需要更新瘟栖,但是不會(huì)立刻開(kāi)始更新。執(zhí)行后會(huì)立刻調(diào)用layoutSubviews谅阿。
  • layoutIfNeeded:告知頁(yè)面布局立刻更新半哟。所以一般都會(huì)和setNeedsLayout一起使用。如果希望立刻生成新的frame需要調(diào)用此方法签餐,利用這點(diǎn)寓涨,動(dòng)畫(huà)可以在更新布局后直接使用這個(gè)方法讓動(dòng)畫(huà)生效。
  • layoutSubviews:系統(tǒng)重寫(xiě)布局
  • setNeedsUpdateConstraints:告知需要更新約束氯檐,但是不會(huì)立刻開(kāi)始
  • updateConstraintsIfNeeded:告知立刻更新約束
  • updateConstraints:系統(tǒng)更新約束
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末戒良,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子冠摄,更是在濱河造成了極大的恐慌糯崎,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評(píng)論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件河泳,死亡現(xiàn)場(chǎng)離奇詭異沃呢,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)拆挥,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén)薄霜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人,你說(shuō)我怎么就攤上這事惰瓜》窀保” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,483評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵崎坊,是天一觀的道長(zhǎng)备禀。 經(jīng)常有香客問(wèn)我,道長(zhǎng)奈揍,這世上最難降的妖魔是什么痹届? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,165評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮打月,結(jié)果婚禮上队腐,老公的妹妹穿的比我還像新娘。我一直安慰自己奏篙,他們只是感情好柴淘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著秘通,像睡著了一般为严。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上肺稀,一...
    開(kāi)封第一講書(shū)人閱讀 51,146評(píng)論 1 297
  • 那天第股,我揣著相機(jī)與錄音,去河邊找鬼话原。 笑死夕吻,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的繁仁。 我是一名探鬼主播涉馅,決...
    沈念sama閱讀 40,032評(píng)論 3 417
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼黄虱!你這毒婦竟也來(lái)了稚矿?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 38,896評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤捻浦,失蹤者是張志新(化名)和其女友劉穎晤揣,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體朱灿,經(jīng)...
    沈念sama閱讀 45,311評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡昧识,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了母剥。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滞诺。...
    茶點(diǎn)故事閱讀 39,696評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡形导,死狀恐怖环疼,靈堂內(nèi)的尸體忽然破棺而出习霹,到底是詐尸還是另有隱情,我是刑警寧澤炫隶,帶...
    沈念sama閱讀 35,413評(píng)論 5 343
  • 正文 年R本政府宣布淋叶,位于F島的核電站,受9級(jí)特大地震影響伪阶,放射性物質(zhì)發(fā)生泄漏煞檩。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評(píng)論 3 325
  • 文/蒙蒙 一栅贴、第九天 我趴在偏房一處隱蔽的房頂上張望斟湃。 院中可真熱鬧,春花似錦檐薯、人聲如沸凝赛。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,659評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)墓猎。三九已至,卻和暖如春赚楚,著一層夾襖步出監(jiān)牢的瞬間毙沾,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,815評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工宠页, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留左胞,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評(píng)論 2 368
  • 正文 我出身青樓举户,卻偏偏與公主長(zhǎng)得像罩句,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子敛摘,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容