Masonry-AutoLayout的第一次使用心得

此前我曾有幾次專門查閱過 AutoLayout 的相關(guān)資料,好吧其實(shí)就是一些牛牛在自己的博客發(fā)表的使用教程及一些心得??。一直都想著試一下但是一直沒有什么時間來實(shí)踐劫侧,這篇文章主要說的是我是怎樣將 Masonry 移植到原有代碼中惭蹂。

如果你的項(xiàng)目中還沒有 Masonry挪捕,你可以通過第三方管理平臺 Cocoapods 來下載谒府,如果有興趣的話,可以看一下我之前整理的關(guān)于 Cocoapods 下載與安裝的文章: IOS依賴管理 - CocoaPods.

首先簡單介紹一下 Masonry浮毯,Masonry 是一款能夠讓開發(fā)者十分容易使用iOS的自動布局(AutoLayout)機(jī)制完疫。Masonry提供更加完善、友好的API來代替直接使用NSLayoutConstraint進(jìn)行編程债蓝,能夠使視圖布局的過程更加輕松壳鹤。(好吧我承認(rèn)這句話是我拷貝過來的??,這不是重點(diǎn))

而我對 Masonry 最初的認(rèn)識是通過這篇文章:Masonry介紹與使用實(shí)踐:快速上手Autolayout - ?CocoaChina 蘋果開發(fā)中文站 - 最熱的iPhone開發(fā)社區(qū) 最熱的蘋果開發(fā)社區(qū) 最熱的iPad開發(fā)社區(qū)饰迹,并且我發(fā)現(xiàn)網(wǎng)絡(luò)上流傳的大部分關(guān)于 Masonry 的文章基本都來自于此芳誓,所以如果你對 Masonry 一點(diǎn)了解都沒有,這篇文章確實(shí)是很不錯的啊鸭。

前期都鋪墊完了锹淌,接下來咱們就看看我是怎樣把原來好好的代碼改成了 Autolayout 的好好的代碼的了??

這是一個餅圖的控件:

之前的代碼是這樣的:

通過 initWithFrame 初始化控件的時候傳進(jìn)來的 frame 計(jì)算餅圖的半徑,根據(jù)計(jì)算出來的半徑確定各個 view 的擺放位置:

- (id)initWithFrame:(CGRect)frame{

? ? self = [super initWithFrame:frame];

? ? if(self){

? ? ? ? ?self.backgroundColor = [UIColor clearColor];

? ? ? ? ?//UIScollView 容器

? ? ? ? ?_scrollContentView = [[UIScrollView alloc] initWithFrame:self.bounds];

? ? ? ? ?_scrollContentView.backgroundColor = [UIColor clearColor];

? ? ? ? ?[self addSubview:_scrollContentView];

? ? ? ? ?//餅圖

? ? ? ? ?_pieView = [[UIView alloc] initWithFrame:self.bounds];

? ? ? ? ?_pieView.backgroundColor = [UIColor clearColor];

? ? ? ? ?[_scrollContentView addSubview:_pieView];

? ? ? ? ?//餅圖中心白色信息區(qū)域

? ? ? ? ?_infoView = [[UIView alloc] initWithFrame:self.bounds];

? ? ? ? ?_infoView.backgroundColor = [UIColor whiteColor];

? ? ? ? ?[_scrollContentView addSubview:_infoView];

? ? ? ? ?//顏色說明

? ? ? ? ?_descriptionView = [[UIView alloc] initWithFrame:self.bounds];

? ? ? ? ?_descriptionView.backgroundColor = [UIColor clearColor];

? ? ? ? ?[_scrollContentView addSubview:_descriptionView];


? ? ? ? ?//計(jì)算餅圖半徑

? ? ? ? ?self.pieRadius = MIN(self.bounds.size.width/2, self.bounds.size.height/2) - kMarginX*2;

? ? ? ? ?self.pieCenter = CGPointMake(self.bounds.size.width/2, _pieRadius + kMarginY);

? ? ? ? ?_animationArr = [NSMutableArray array];

? ? ? ? ?self.textRadius = _pieRadius - (_pieRadius-kInfoRadius)/2;

? ? ? ? ?}

? ? return self;

}


- (void)setPieCenter:(CGPoint)pieCenter{

? ? [_pieView setCenter:pieCenter];

? ? [_infoView setCenter:pieCenter];

? ? //這個點(diǎn)是方便用來在餅圖上面畫扇葉用的赠制,是以餅圖為基準(zhǔn)的中心值

? ? _pieCenter = CGPointMake(_pieView.frame.size.width/2, _pieView.frame.size.height/2);

}

- (void)setPieRadius:(CGFloat)pieRadius{

? ? _pieRadius = pieRadius;

? ? CGRect frame = CGRectMake(_pieCenter.x - pieRadius, _pieCenter.y - pieRadius, pieRadius*2, pieRadius*2);

? ? _pieCenter = CGPointMake(frame.size.width/2,frame.size.height/2);

? ? //設(shè)置餅圖 frame

? ? [_pieView setFrame:frame];

? ? [_pieView.layer setCornerRadius:_pieRadius];

? ? CGFloat infoRadius = kInfoRadius;

? ? frame = CGRectMake(_pieCenter.x - infoRadius, _pieCenter.y - infoRadius, infoRadius*2, infoRadius*2);

? ? //設(shè)置白色信息圖 frame

? ? [_infoView setFrame:frame];

? ? [_infoView.layer setCornerRadius:infoRadius];

}

從上面的代碼赂摆,你應(yīng)該能看出代碼原來的邏輯順序,這樣處理代碼的目的就是通過在初始化這個控件的時候就根據(jù)給定的 frame 寬高取最小值作為餅圖的直徑钟些,進(jìn)而確定餅圖以及白色信息圖的frame烟号,但是前提我剛說了,一切都建立在 frame 是一個給出的固定值的基礎(chǔ)上的政恍。我這樣說你可能會覺得奇怪汪拥,frame 本來就是一個固定好的確切的CGRect 啊什么鬼啊是不是神經(jīng)啊?? 那么什么情況下你并不知道 frame 到底是多少呢?那就是我在初始化這個控件的時候也用了 AutoLayout篙耗,也就是說我在上一個界面就是通過約束來管理這個控件的布局迫筑,那么我只需要給定約束條件就好并不需要傳一個固定的值來給這個控件,像這樣:

WS(weakSelf);

_pie = [[PieChart alloc] initWithFrame:CGRectZero];

_pie.dataSource = self;

[self.view addSubview:_pie];

[_pie mas_makeConstraints:^(MASConstraintMaker *make) {

? ? make.edges.equalTo(weakSelf.view);

}];

就像你看到的鹤树,我在初始化的時候并沒有給出一個固定好的有用的 frame铣焊,而是加了一句約束條件,這一句話的意思就是 pie 的大小要跟當(dāng)前的 view 一樣大罕伯,是的曲伊,這一切都是自動的。

那么現(xiàn)在我要做的就是讓 pie 里面的部分控件也 autoLayout,但是我還是需要把 view 的 frame 告訴 pie,因?yàn)槲以居幸粋€邏輯是需要取frame 寬高最小值來作為餅圖的直徑的坟募,真惱人岛蚤,那么我們就應(yīng)該想辦法告訴 pie 我現(xiàn)在的 frame 是多大,你再來做相應(yīng)調(diào)整懈糯。好吧涤妒,我先來通知 pie:

-(void)viewWillAppear:(BOOL)animated{

? ? [super viewWillAppear:animated];

? ? _pie.frame = self.view.bounds;

}

那么現(xiàn)在我在 pie 里就需要改了:

- (id)initWithFrame:(CGRect)frame{

? ? self = [super initWithFrame:frame];

? ? if(self){

? ? ? ? ? self.backgroundColor = [UIColor clearColor];

? ? ? ? ?WS(weakSelf);

? ? ? ? ?_scrollContentView = [[UIScrollView alloc] initWithFrame:self.bounds];

? ? ? ? ?_scrollContentView.backgroundColor = [UIColor clearColor];

? ? ? ? ?[self addSubview:_scrollContentView];

? ? ? ? ?[_scrollContentView mas_makeConstraints:^(MASConstraintMaker *make) {

? ? ? ? ? ? ? //重點(diǎn)來了,scrollview 要求跟當(dāng)前 view 一邊大

? ? ? ? ? ? ? make.edges.equalTo(weakSelf);

? ? ? ? ?}];


? ? ? ? ?__weak UIScrollView *weakScroll = _scrollContentView;

? ? ? ? ?_pieView = [[UIView alloc] initWithFrame:self.bounds];

? ? ? ? ?_pieView.backgroundColor = [UIColor clearColor];

? ? ? ? ?[_scrollContentView addSubview:_pieView];

? ? ? ? ?[_pieView mas_makeConstraints:^(MASConstraintMaker *make) {

? ? ? ? ? ? ? //餅圖中心點(diǎn) X 值要跟 scrollview 一樣赚哗,頭部要在 scrollview 上留出kMarginY大小的距離

? ? ? ? ? ? ? make.centerX.equalTo(weakScroll.centerX);

? ? ? ? ? ? ? make.top.equalTo(weakScroll.top).with.offset(kMarginY);

? ? ? ? ?}];


? ? ? ? ?__weak UIView *weakPie = _pieView;

? ? ? ? ?_infoView = [[UIView alloc] initWithFrame:self.bounds];

? ? ? ? ?_infoView.backgroundColor = [UIColor whiteColor];

? ? ? ? ?[_scrollContentView addSubview:_infoView];

? ? ? ? ?[_infoView mas_makeConstraints:^(MASConstraintMaker *make) {

? ? ? ? ? ? ? //白色信息圖的中心點(diǎn) X 值 Y 值都要跟餅圖一樣

? ? ? ? ? ? ? make.centerX.equalTo(weakPie.centerX);

? ? ? ? ? ? ? make.centerY.equalTo(weakPie.centerY);

? ? ? ? ?}];


? ? ? ? ?_descriptionView = [[UIView alloc] initWithFrame:self.bounds];

? ? ? ? ?_descriptionView.backgroundColor = [UIColor clearColor];

? ? ? ? ?[_scrollContentView addSubview:_descriptionView];

? ? ? ? ?[_descriptionView mas_makeConstraints:^(MASConstraintMaker *make) {

? ? ? ? ? ? ? //顏色說明 view 的寬度要跟 scrollview 一樣她紫,頭部要在餅圖底部距離kPieDesSpace的位置

? ? ? ? ? ? ? make.width.equalTo(weakScroll);

? ? ? ? ? ? ? make.top.equalTo(weakPie.bottom).with.offset(kPieDesSpace);

? ? ? ? ?}];

? ?}

? ? return self;

}

-(void)setFrame:(CGRect)frame{

? ? [super setFrame:frame];

? ? self.pieRadius = MIN(self.bounds.size.width/2, self.bounds.size.height/2) - kMarginX*2;

? ? _animationArr = [NSMutableArray array];

? ? self.textRadius = _pieRadius - (_pieRadius-kInfoRadius)/2;

? ? //注意這里用到的是 update,因?yàn)槲抑耙呀?jīng)對他們設(shè)置過約束屿储,我只是想添加新的約束贿讹,如果還是用make 的話之前的所有約束都會無效,如果用 remake 的話就是把之前的相應(yīng)約束替換掉够掠。因?yàn)槲椰F(xiàn)在已經(jīng)知道 frame 了民褂,現(xiàn)在我可以將他們的大小進(jìn)行約束了

? ? [_pieView updateConstraints:^(MASConstraintMaker *make) {

? ? ? ? ?make.size.mas_equalTo(CGSizeMake(_pieRadius*2, _pieRadius*2));

? ? }];

? ? [_infoView updateConstraints:^(MASConstraintMaker *make) {

? ? ? ? ?make.size.mas_equalTo(CGSizeMake(kInfoRadius *2, kInfoRadius *2));

? ? }];

}

- (void)setPieRadius:(CGFloat)pieRadius{

? ? _pieRadius = pieRadius;

? ? [_pieView.layer setCornerRadius:_pieRadius];

? ? [_infoView.layer setCornerRadius:kInfoRadius];

}

完成。

我已經(jīng)不想再說什么啦疯潭,這個代碼為毛只能一行一行的復(fù)制粘貼進(jìn)去霸伞赦政!并且我的空格怎么都不見了啊!我是手動的敲的這些空格疤棠弧6パ唷欢瞪!手都快抽筋了啊啊暗型辍!6鄣础街立!

好吧,其實(shí)這個復(fù)制粘貼代碼這么難用我還是堅(jiān)持著手動一行一行復(fù)制粘貼下來空格敲的這么完美埠通,都是因?yàn)槲业暮门笥言趲臀艺易钕矚g吃的櫻桃準(zhǔn)備給我寄過來赎离!我不禁哼起歌來~一想到這呀~就讓我快樂~貼一張圖饞饞你們哈哈哈!


圖片發(fā)自簡書App

噢噢太激動了忘記了總結(jié)??

其實(shí)一開始用autolayout我是拒絕的端辱,想到要xb梁剔、sb還有官方那么繁瑣的語句喔喔還有那個看不懂的象形文字??我就渾身腦袋疼!但是現(xiàn)在有了這么方便的Masonry舞蔽,就學(xué)來用用吧荣病,畢竟蘋果的屏幕大小已經(jīng)開始不一樣了,用一個朋友的話來說渗柿,autolayout是趨勢个盆。不管怎樣脖岛,了解下總是好的??

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市颊亮,隨后出現(xiàn)的幾起案子柴梆,更是在濱河造成了極大的恐慌,老刑警劉巖终惑,帶你破解...
    沈念sama閱讀 207,248評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绍在,死亡現(xiàn)場離奇詭異,居然都是意外死亡雹有,警方通過查閱死者的電腦和手機(jī)偿渡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來霸奕,“玉大人卸察,你說我怎么就攤上這事∏觯” “怎么了?”我有些...
    開封第一講書人閱讀 153,443評論 0 344
  • 文/不壞的土叔 我叫張陵合武,是天一觀的道長临梗。 經(jīng)常有香客問我,道長稼跳,這世上最難降的妖魔是什么盟庞? 我笑而不...
    開封第一講書人閱讀 55,475評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮汤善,結(jié)果婚禮上什猖,老公的妹妹穿的比我還像新娘。我一直安慰自己红淡,他們只是感情好不狮,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評論 5 374
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著在旱,像睡著了一般摇零。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上桶蝎,一...
    開封第一講書人閱讀 49,185評論 1 284
  • 那天驻仅,我揣著相機(jī)與錄音,去河邊找鬼登渣。 笑死噪服,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的胜茧。 我是一名探鬼主播粘优,決...
    沈念sama閱讀 38,451評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了敬飒?” 一聲冷哼從身側(cè)響起邪铲,我...
    開封第一講書人閱讀 37,112評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎无拗,沒想到半個月后带到,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡英染,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評論 2 325
  • 正文 我和宋清朗相戀三年揽惹,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片四康。...
    茶點(diǎn)故事閱讀 38,163評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡搪搏,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出闪金,到底是詐尸還是另有隱情疯溺,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評論 4 323
  • 正文 年R本政府宣布哎垦,位于F島的核電站囱嫩,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏漏设。R本人自食惡果不足惜墨闲,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望郑口。 院中可真熱鬧鸳碧,春花似錦、人聲如沸犬性。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乒裆。三九已至琐脏,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間缸兔,已是汗流浹背日裙。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惰蜜,地道東北人昂拂。 一個月前我還...
    沈念sama閱讀 45,636評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像抛猖,于是被迫代替她去往敵國和親格侯。 傳聞我的和親對象是個殘疾皇子鼻听,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評論 2 344

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