FlexBox - YogaKit

FlexBox - YogaKit

FlexBox是一套通用的布局協(xié)議呀潭,YogaKit實(shí)現(xiàn)了這個(gè)協(xié)議莽鸿,iOS端可以使用YogaKit來實(shí)現(xiàn)FlexBox布局听系。FlexBox和UIStackView以及Android的LineLayout有相通的地方虑润,優(yōu)勢(shì)在于FlexBox是跨平臺(tái)的肥荔,功能上也更強(qiáng)一點(diǎn)弥臼。

YogaKit依據(jù)你的設(shè)置計(jì)算出相關(guān)的view的frame,直接設(shè)置frame,所以和AutoLayout可以混合使用宴咧,對(duì)同一個(gè)view進(jìn)行設(shè)置,以AutoLayout的設(shè)置為準(zhǔn)径缅。

YogaKit是從從上往下進(jìn)行計(jì)算的掺栅,使用過程中需要保證flex container的frame有值,這樣它的flex item才會(huì)計(jì)算出frame纳猪,否則都是CGRectZero氧卧。

flex direction

布局延伸的方向,確定了主軸和副軸氏堤,添加的元素沿著主軸的方向進(jìn)行排列沙绝。

  • Row

    水平方向從左往右進(jìn)行延伸,主軸為水平方向鼠锈,副軸為豎直方向

  • Row Reverse

    水平方向從左往右進(jìn)行延伸闪檬,主軸為水平方向,副軸為豎直方向

  • Column

    豎直方向從上往下進(jìn)行延伸购笆,主軸為豎直方向粗悯,副軸為水平方向

  • Column Reverse

    豎直方向從下往上進(jìn)行延伸,主軸為豎直方向同欠,副軸為水平方向

justify & align-items

justify 進(jìn)一步明確了元素在主軸方向如何排列样傍,align-items 進(jìn)一步明確了元素在副軸方向如何排列

  • flex start
  • center
  • end
  • space between
  • space around
  • space evenly
  • stretch

flex-wrap (適用于父類容器上)

設(shè)置或檢索伸縮盒對(duì)象的子元素超出父容器時(shí)是否換行

padding & margin

iOS 上 padding 對(duì)應(yīng)的是 content inserts,但是 iOS 大部分控件都沒有padding,相信很多人都寫過一個(gè)繼承自 UILabel的控件來提供設(shè)置 content inserts 的控件行您,有了YogaKit,那個(gè)類以后用不上了剪廉。

padding 指的是自身內(nèi)邊距娃循,margin 指的是外邊距,@"H:|-20-[redView]-20-|"斗蒋,這條VFL里的20就是margin捌斧。

display

是否顯示這個(gè)元素笛质,如果為none,則不顯示,也不參與計(jì)算

markDirty

標(biāo)記元素需要重新計(jì)算位置捞蚂,只對(duì)葉子節(jié)點(diǎn)生效妇押。

// 獲取驗(yàn)證碼 -> 重發(fā)
- (void)codeButtonClicked:(UIButton *)button {
    [button setTitle:@"重發(fā)" forState:UIControlStateNormal];
    button.superview.yoga.marginTop = YGPointValue(0);
    [button.yoga markDirty];
    [button.superview.yoga applyLayoutPreservingOrigin:YES];
}

flexGrow

flexGrow決定剩余空間怎么分配,含義類似于layout_weight.如果flex item的flexGrow為0姓迅,該flex item不會(huì)占用剩余的空間敲霍。如果多個(gè)flex item的flexGrow不為0,則按flexGrow的值按比例進(jìn)行劃分丁存。

flexShrink

flexShrink決定空間不足肩杈,怎么縮放

align-items、align-self解寝、align-content扩然、

  • align-item

    屬性需要施加在 flex 容器上,它規(guī)定的是 flex 容器中所有 item 在副軸中的對(duì)齊方式

    // flex item在副軸拉伸填滿剩余空間
    layout.alignItems = YGAlignStretch;
    
  • align-self

    屬性則施加在 flex 容器中的 item 上聋伦,允許單個(gè)項(xiàng)目有與其他項(xiàng)目不一樣的對(duì)齊方式夫偶,它覆蓋了外部容器規(guī)定的 align-items 屬性,同樣也只規(guī)定在交叉軸上的對(duì)齊方式

  • align-content

    對(duì)比 align-items 和 align-self 直接移動(dòng) item 自身在交叉軸上的基線觉增,align-content 移動(dòng)的是容器自身的 flex line兵拢,并僅對(duì)多行的項(xiàng)目起作用

常見問題

  • Pod

    使用pod 'YogaKit'安裝的時(shí)候,這個(gè)庫包含了一個(gè)swift文件抑片,對(duì)于純OC的項(xiàng)目卵佛,這會(huì)報(bào)錯(cuò)。

    可以改成

    pod 'IGListKit','2.1.0'
    pod 'Yoga','1.14.0'
    

    然后將YogaKit的代碼(刪除掉swfit文件后)copy到項(xiàng)目中敞斋,這部分不使用cocopods進(jìn)行管理截汪,這樣改動(dòng)比較小

  • AutoLayout

    YogaKit布局設(shè)置的是view的frame,所以如果對(duì)視圖添加約束植捎,視圖最終的大小以約束設(shè)置為準(zhǔn)衙解。

    涉及到其他的視圖時(shí),參與計(jì)算的是YogaKit自己計(jì)算出來的view.frame,而不是約束設(shè)置的值焰枢。

實(shí)踐

標(biāo)簽流式布局

- (void)tagLayout {
    NSArray *tags = @[@"投資理財(cái)",@"超高收益",@"七日年化收益",@"支付寶",@"微信",@"云閃付",@"花唄"];
    
    UIView *tagBgView = [[UIView alloc] init];
    
    tagBgView.backgroundColor = [UIColor lightGrayColor];
    [tagBgView configureLayoutWithBlock:^(YGLayout * _Nonnull layout) {
        layout.isEnabled = YES;
        layout.flexDirection = YGFlexDirectionRow;
        layout.marginTop = YGPointValue(100);
        layout.paddingBottom = YGPointValue(10);
        layout.width = YGPointValue([UIScreen mainScreen].bounds.size.width); 
        // 不設(shè)置高度蚓峦,讓高度自適應(yīng)
        layout.flexWrap = YGWrapWrap;
    }];
    
    [self.view addSubview:tagBgView];
    
    for (NSString *obj in tags) {
        UILabel *label = [[UILabel alloc] init];
        
        label.text = obj;
        label.backgroundColor = [UIColor orangeColor];
        [label configureLayoutWithBlock:^(YGLayout * _Nonnull layout) {
            layout.isEnabled =YES;
            layout.marginLeft = YGPointValue(10);
            layout.marginTop = YGPointValue(10);
        }];
        
        [tagBgView addSubview:label];
    }
        
    self.view.yoga.isEnabled = YES;
    [self.view.yoga applyLayoutPreservingOrigin:NO];
}

<img src="https://i.loli.net/2019/10/10/sdIMwUluPVoCBrN.png" alt="截屏2019-10-10下午5.30.21.png" style="zoom:50%;" />

更新布局

很多時(shí)候,我們的視圖大小是依據(jù)視圖內(nèi)容來決定的,比如按鈕的寬依據(jù)title進(jìn)行調(diào)整济锄,title變了暑椰,寬也要變,暫時(shí)只找到用markDirty實(shí)現(xiàn)的方法荐绝。

FlexBox是一套通用的布局協(xié)議一汽,YogaKit實(shí)現(xiàn)了這個(gè)協(xié)議,iOS端可以使用YogaKit來實(shí)現(xiàn)FlexBox布局低滩。FlexBox和UIStackView以及Android的LineLayout有相通的地方召夹,優(yōu)勢(shì)在于FlexBox是跨平臺(tái)的岩喷,功能上也更強(qiáng)一點(diǎn)。

YogaKit依據(jù)你的設(shè)置計(jì)算出相關(guān)的view的frame,直接設(shè)置frame,所以和AutoLayout可以混合使用监憎,對(duì)同一個(gè)view進(jìn)行設(shè)置纱意,以AutoLayout的設(shè)置為準(zhǔn)。

YogaKit是從從上往下進(jìn)行計(jì)算的鲸阔,使用過程中需要保證flex container的frame有值偷霉,這樣它的flex item才會(huì)計(jì)算出frame,否則都是CGRectZero隶债。

flex direction

布局延伸的方向腾它,確定了主軸和副軸,添加的元素沿著主軸的方向進(jìn)行排列死讹。

  • Row

    水平方向從左往右進(jìn)行延伸瞒滴,主軸為水平方向,副軸為豎直方向

  • Row Reverse

    水平方向從左往右進(jìn)行延伸赞警,主軸為水平方向妓忍,副軸為豎直方向

  • Column

    豎直方向從上往下進(jìn)行延伸,主軸為豎直方向愧旦,副軸為水平方向

  • Column Reverse

    豎直方向從下往上進(jìn)行延伸世剖,主軸為豎直方向,副軸為水平方向

justify & align-items

justify 進(jìn)一步明確了元素在主軸方向如何排列笤虫,align-items 進(jìn)一步明確了元素在副軸方向如何排列

  • flex start
  • center
  • end
  • space between
  • space around
  • space evenly
  • stretch

flex-wrap (適用于父類容器上)

設(shè)置或檢索伸縮盒對(duì)象的子元素超出父容器時(shí)是否換行

padding & margin

iOS 上 padding 對(duì)應(yīng)的是 content inserts旁瘫,但是 iOS 大部分控件都沒有padding,相信很多人都寫過一個(gè)繼承自 UILabel的控件來提供設(shè)置 content inserts 的控件,有了YogaKit琼蚯,那個(gè)類以后用不上了酬凳。

padding 指的是自身內(nèi)邊距,margin 指的是外邊距遭庶,@"H:|-20-[redView]-20-|"宁仔,這條VFL里的20就是margin。

display

是否顯示這個(gè)元素峦睡,如果為none,則不顯示翎苫,也不參與計(jì)算

markDirty

標(biāo)記元素需要重新計(jì)算位置,只對(duì)葉子節(jié)點(diǎn)生效榨了。

// 獲取驗(yàn)證碼 -> 重發(fā)
- (void)codeButtonClicked:(UIButton *)button {
    [button setTitle:@"重發(fā)" forState:UIControlStateNormal];
    button.superview.yoga.marginTop = YGPointValue(0);
    [button.yoga markDirty];
    [button.superview.yoga applyLayoutPreservingOrigin:YES];
}

flexGrow

flexGrow決定剩余空間怎么分配煎谍,含義類似于layout_weight.如果flex item的flexGrow為0,該flex item不會(huì)占用剩余的空間龙屉。如果多個(gè)flex item的flexGrow不為0呐粘,則按flexGrow的值按比例進(jìn)行劃分。

flexShrink

flexShrink決定空間不足,怎么縮放

align-items事哭、align-self、align-content瓜富、

  • align-item

    屬性需要施加在 flex 容器上鳍咱,它規(guī)定的是 flex 容器中所有 item 在副軸中的對(duì)齊方式

    // flex item在副軸拉伸填滿剩余空間
    layout.alignItems = YGAlignStretch;
    
  • align-self

    屬性則施加在 flex 容器中的 item 上,允許單個(gè)項(xiàng)目有與其他項(xiàng)目不一樣的對(duì)齊方式与柑,它覆蓋了外部容器規(guī)定的 align-items 屬性谤辜,同樣也只規(guī)定在交叉軸上的對(duì)齊方式

  • align-content

    對(duì)比 align-items 和 align-self 直接移動(dòng) item 自身在交叉軸上的基線,align-content 移動(dòng)的是容器自身的 flex line价捧,并僅對(duì)多行的項(xiàng)目起作用

常見問題

  • Pod

    使用pod 'YogaKit'安裝的時(shí)候丑念,這個(gè)庫包含了一個(gè)swift文件,對(duì)于純OC的項(xiàng)目结蟋,這會(huì)報(bào)錯(cuò)脯倚。

    可以改成

    pod 'IGListKit','2.1.0'
    pod 'Yoga','1.14.0'
    

    然后將YogaKit的代碼(刪除掉swfit文件后)copy到項(xiàng)目中,這部分不使用cocopods進(jìn)行管理嵌屎,這樣改動(dòng)比較小

  • AutoLayout

    YogaKit布局設(shè)置的是view的frame推正,所以如果對(duì)視圖添加約束,視圖最終的大小以約束設(shè)置為準(zhǔn)宝惰。

    涉及到其他的視圖時(shí)植榕,參與計(jì)算的是YogaKit自己計(jì)算出來的view.frame,而不是約束設(shè)置的值。

實(shí)踐

標(biāo)簽流式布局

- (void)tagLayout {
    NSArray *tags = @[@"投資理財(cái)",@"超高收益",@"七日年化收益",@"支付寶",@"微信",@"云閃付",@"花唄"];
    
    UIView *tagBgView = [[UIView alloc] init];
    
    tagBgView.backgroundColor = [UIColor lightGrayColor];
    [tagBgView configureLayoutWithBlock:^(YGLayout * _Nonnull layout) {
        layout.isEnabled = YES;
        layout.flexDirection = YGFlexDirectionRow;
        layout.marginTop = YGPointValue(100);
        layout.paddingBottom = YGPointValue(10);
        layout.width = YGPointValue([UIScreen mainScreen].bounds.size.width); 
        // 不設(shè)置高度尼夺,讓高度自適應(yīng)
        layout.flexWrap = YGWrapWrap;
    }];
    
    [self.view addSubview:tagBgView];
    
    for (NSString *obj in tags) {
        UILabel *label = [[UILabel alloc] init];
        
        label.text = obj;
        label.backgroundColor = [UIColor orangeColor];
        [label configureLayoutWithBlock:^(YGLayout * _Nonnull layout) {
            layout.isEnabled =YES;
            layout.marginLeft = YGPointValue(10);
            layout.marginTop = YGPointValue(10);
        }];
        
        [tagBgView addSubview:label];
    }
        
    self.view.yoga.isEnabled = YES;
    [self.view.yoga applyLayoutPreservingOrigin:NO];
}
截圖

更新布局

很多時(shí)候尊残,我們的視圖大小是依據(jù)視圖內(nèi)容來決定的,比如按鈕的寬依據(jù)title進(jìn)行調(diào)整,title變了淤堵,寬也要變寝衫,暫時(shí)只找到用markDirty實(shí)現(xiàn)的方法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末粘勒,一起剝皮案震驚了整個(gè)濱河市竞端,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌庙睡,老刑警劉巖事富,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異乘陪,居然都是意外死亡统台,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門啡邑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來贱勃,“玉大人,你說我怎么就攤上這事」笕牛” “怎么了仇穗?”我有些...
    開封第一講書人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)戚绕。 經(jīng)常有香客問我纹坐,道長(zhǎng),這世上最難降的妖魔是什么舞丛? 我笑而不...
    開封第一講書人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任耘子,我火速辦了婚禮,結(jié)果婚禮上球切,老公的妹妹穿的比我還像新娘谷誓。我一直安慰自己,他們只是感情好吨凑,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開白布捍歪。 她就那樣靜靜地躺著,像睡著了一般鸵钝。 火紅的嫁衣襯著肌膚如雪费封。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,624評(píng)論 1 305
  • 那天蒋伦,我揣著相機(jī)與錄音弓摘,去河邊找鬼。 笑死痕届,一個(gè)胖子當(dāng)著我的面吹牛韧献,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播研叫,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼锤窑,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了嚷炉?” 一聲冷哼從身側(cè)響起渊啰,我...
    開封第一講書人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎申屹,沒想到半個(gè)月后绘证,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡哗讥,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年嚷那,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片杆煞。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡魏宽,死狀恐怖腐泻,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情队询,我是刑警寧澤派桩,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站蚌斩,受9級(jí)特大地震影響窄坦,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜凳寺,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望彤侍。 院中可真熱鬧肠缨,春花似錦、人聲如沸盏阶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽名斟。三九已至脑慧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間砰盐,已是汗流浹背闷袒。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留岩梳,地道東北人囊骤。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像冀值,于是被迫代替她去往敵國(guó)和親也物。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

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