簡(jiǎn)直是神了!iOS開(kāi)發(fā)中利用setFrame快速對(duì)視圖布局

前言

iOS開(kāi)發(fā)布局有多套方案可以實(shí)現(xiàn),大致有幾種方法。NSLayoutConstraint, Masonry, Snapkit(Swift環(huán)境布局框架),也可以用setframe來(lái)實(shí)現(xiàn)簡(jiǎn)單的布局。

  • NSLayoutConstraint:蘋(píng)果官方推出的約束方式,在XIB或故事板中可以使用拖拽快速實(shí)現(xiàn),純代碼實(shí)現(xiàn)起來(lái)顯得相當(dāng)繁瑣。
  • Masony: 一款經(jīng)典的三方布局框架,由Objective-C語(yǔ)言編寫(xiě),適用于純代碼布局,相對(duì)于官方的NSLayoutConstraint是用代碼布局而言,可以在一個(gè)block中實(shí)現(xiàn)對(duì)單一控件實(shí)現(xiàn)完整布局,有著很高的布局效率,缺點(diǎn)是有侵入性,代碼的可以閱讀性不夠好。
  • Snapkit: Swift版本的Masony,適用于由Swift語(yǔ)言搭建的項(xiàng)目,布局是在閉包中完成的。
  • setFrame方法:利用系統(tǒng)的setFrame方法,可以實(shí)現(xiàn)快速的控件靜態(tài)布局。setFrame方式需要準(zhǔn)確的計(jì)算出控件的origin(原點(diǎn)坐標(biāo)),size(尺寸),繁瑣的計(jì)算導(dǎo)致該方法在使用中顯得不夠靈活,在屏幕適配中顯得很麻煩。
  • 還有其他的一些布局方式,github上可以找到很多類(lèi)型的解決方案。有的太重量級(jí),有的太繁瑣,有的和系統(tǒng)布局的兼容性存在問(wèn)題。

我的Idea

根據(jù)多年的iOS開(kāi)發(fā)經(jīng)驗(yàn)。我自己對(duì)setFrame做了一個(gè)簡(jiǎn)單的封裝,實(shí)現(xiàn)了對(duì)控件的簡(jiǎn)單布局。使用起來(lái)棒棒噠,如果下列代碼能夠吸引你,那么請(qǐng)繼續(xù)看下去:

[_detailAddressLabel setFrameFromLayout:^(UIViewVirtualLayout *layout) {
                    layout.size = CGSizeMake(80.0, 40.0);
                    layout.yCenter = cell.contentView.h / 2.0;
                    layout.x = 15.0;
                }];

很顯然的,上述代碼其實(shí)就是被我含蓄地setFrame了,但是我?guī)缀鯖](méi)有做什么計(jì)算我就把這個(gè)布局給完成了。一個(gè)地址Label,設(shè)置它的尺寸為 80 * 40, 縱坐標(biāo)中心與它所在的cell的中心對(duì)齊,橫坐標(biāo)為15,是不是很簡(jiǎn)單呢。
我們?cè)賮?lái)看看Masony是怎么布局的;

 [_detailAddressLabel makeConstraints:^(MASConstraintMaker *make) {
                    make.width.equalTo(80.0);
                    make.height.equalTo(40.0);
                    make.left.equalTo(cell.contentView.left).offset(15.0);
                    make.centerY.equalTo(cell.contentView);
                }];

看起來(lái)出入不大,但是我可以告訴你,從程序的運(yùn)行角度來(lái)說(shuō),通過(guò)我封裝UIViewVirtualLayout方式來(lái)實(shí)現(xiàn)對(duì)控件的布局運(yùn)行效率要高很多,關(guān)鍵是封裝原理十分淺顯易懂。 極大地降低了程序的體積,還降低了冗余。
當(dāng)然setFrame的布局是靜態(tài)的,如果控件相對(duì)于參照控件,布局是發(fā)生變化的,就需要在變化時(shí)去調(diào)用一下該方法,比如在tableViewCell或collectionViewCell中,就可以在cell的layoutSubViews方法中去調(diào)用setFrameFromLayout:方法。這個(gè)方法可用于創(chuàng)建布局和刷新布局,免去了像Masony中UpdateConstrains方法的麻煩。

實(shí)現(xiàn)

具體實(shí)現(xiàn)簡(jiǎn)單到爆,只怕沒(méi)想到,誰(shuí)都能做到。
在實(shí)現(xiàn)中我對(duì)UIView設(shè)置了一個(gè)類(lèi)別,專(zhuān)用于對(duì)UIView及其子類(lèi)進(jìn)行改變frame,當(dāng)然一次只能改變一個(gè)參數(shù),對(duì)于改變frame中的一個(gè)參數(shù)來(lái)說(shuō),是非常高效的,免去了計(jì)算坐標(biāo)的麻煩,但是如果要一起把UIView的所有坐標(biāo)屬性設(shè)定,則需要反復(fù)調(diào)用setFrame,所以對(duì)于布局來(lái)說(shuō)這樣還不是一個(gè)很好的解決方案。為了布局的快速實(shí)現(xiàn)并提高運(yùn)行效率,這里引入了UIViewVirtualLayout類(lèi)(后面簡(jiǎn)稱(chēng)layout),我們利用layout來(lái)實(shí)現(xiàn)對(duì)frame的賦值,知道layout全部參數(shù)設(shè)定完成后再去賦值給view的frame,在這期間只對(duì)frame刷新一次。

UIView+Layout類(lèi)別中的布局實(shí)現(xiàn)代碼

- (void)setFrameFromLayout:(VirtualLayoutBlock)layoutBlock {
    UIViewVirtualLayout * layout = [[UIViewVirtualLayout alloc] init];
    layout.frame = self.frame;
    layoutBlock(layout);
    [self setFrame:layout.frame];
}

顯然的,layout相當(dāng)于是一個(gè)布局的數(shù)據(jù)緩存,當(dāng)他設(shè)定好值,再把值賦值給view的frame,完成它的使命。
代碼已經(jīng)上傳到github,具體實(shí)現(xiàn)請(qǐng)參見(jiàn) https://github.com/cba023/QuicklySetFrame

謝謝。

2018-05-17

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 目錄 0、前言 一、Auto Layout前世今生 二、Auto Layout基礎(chǔ)知識(shí) 1.Auto Layout...
    浮游lb閱讀 25,476評(píng)論 3 90
  • 小區(qū)里與娃媽聊天,她家娃今年五歲了,一直沒(méi)有送幼兒園,不是差錢(qián),而是覺(jué)得幼兒園沒(méi)啥用處,還不如給孩子一個(gè)快樂(lè)的童年...
    夢(mèng)婷兒閱讀 630評(píng)論 0 1
  • 客棧老板娘建議我們今天去木坑竹海和漂流,而不要去西遞了,本來(lái)有點(diǎn)憂郁,因?yàn)榍皫滋靹傇谀缮接^賞過(guò)竹海,加上爬山有點(diǎn)...
    張方平閱讀 429評(píng)論 0 0
  • 1ד2011.11.11 因?yàn)橛鲆?jiàn)你,我突然想要安定下來(lái)?!?t寶發(fā)給一一的第一條手機(jī)短信是“猜猜我是誰(shuí)。” 時(shí)...
    簡(jiǎn)一姑娘吶閱讀 495評(píng)論 0 0
  • 最近一直在嘗試一些新的模塊化工具,發(fā)現(xiàn)了 gulp 比較好用,但是之前使用過(guò)一段時(shí)間的grunt,所以根據(jù)以下幾個(gè)...
    Simon王小白閱讀 428評(píng)論 0 0

友情鏈接更多精彩內(nèi)容