iOS 中使用 FlexBox 布局實(shí)現(xiàn)圖片九宮格

首發(fā)于公眾號(hào)

在 iOS 中官方支持的布局方式是 AutoLayout,是一種基于控件之間相互約束關(guān)系的自動(dòng)布局工具。

官方的 AutoLayout 雖然用起來(lái)簡(jiǎn)單,但是有兩個(gè)非常不方便的地方:

  1. 原生 API 接口使用不友好
  2. 約束越多性能損失越多

第1個(gè)問(wèn)題可以使用第三方庫(kù)來(lái)解決,比如 SnapKit(swift)、Masonry(oc)。
性能問(wèn)題則無(wú)解,對(duì)于混合布局的 Cell 如果全部使用自動(dòng)布局就會(huì)看到很明顯的滑動(dòng)卡頓。

對(duì)于復(fù)雜 Cell 布局,程序員們?yōu)榱俗非髽O致的幀率,一般都采用手寫布局,幀率是上去了而維護(hù)的成本也最高。

為了兼顧易用性和高效率,F(xiàn)acebook 開(kāi)發(fā)并開(kāi)源了自己的布局庫(kù):Yoga。

Yoga 是 FlexBox 的子集,并沒(méi)有全部實(shí)現(xiàn) FlexBox,但是對(duì)于大部分應(yīng)用場(chǎng)景已經(jīng)足夠了。

接觸過(guò)前端開(kāi)發(fā)的朋友對(duì) FlexBox 布局一定不陌生,CSS 寫 flex 布局真的太方便了。

FlexBox 是不同于 AutoLayout 的布局方式,F(xiàn)lexBox 是自約束,每個(gè)控件的位置都是相對(duì)于自身所在的 Box 相對(duì)布局,這就不存在 AutoLayout 基于控件間約束的耦合。

Yoga 是基于手動(dòng)布局的方式,這樣效率就很高,而且性能損耗很小,而且使用很簡(jiǎn)單,用過(guò) Masonry 的同學(xué)可以很快上手。

使用方法:

override init(frame: CGRect) {
  super.init(frame: frame)
  contentView.configureLayout { (layout) in
  layout.isEnabled = true
}

override func layoutSubviews() {
  super.layoutSubviews()
   yoga.applyLayout(preservingOrigin: true)
}

layout.isEnabled = true 開(kāi)啟 yoga 布局,
在 layoutSubviews 中使用 applyLayout 自動(dòng)調(diào)整布局。

這和手動(dòng)布局的流程是一樣的,可以看出來(lái) yoga 本質(zhì)上也是手動(dòng)布局,只是再也不用手算坐標(biāo)了。

yoga 同時(shí)也有很好的易用性,比如要實(shí)現(xiàn)一個(gè)簡(jiǎn)單的九宮格,只需要簡(jiǎn)單的設(shè)置一下布局參數(shù)。

override init(frame: CGRect) {
  super.init(frame: frame)

  configureLayout { (layout) in
  layout.isEnabled = true
  }

  contentView = UIView(frame: bounds)
  addSubview(contentView)
  contentView.configureLayout { (layout) in
    layout.isEnabled = true
    layout.flexDirection = .row
    layout.flexWrap = .wrap
    layout.flexGrow = 1
  }

  for _ in 0...8 {
    let imageView = UIImageView(frame: .zero)
    imageView.backgroundColor = .orange
    contentView.addSubview(imageView)
    imageView.configureLayout { (layout) in
      layout.isEnabled = true
      layout.width = 86
      layout.height = 86
      layout.marginTop = 10
      layout.marginLeft = 10
    }
  }
}

override func layoutSubviews() {
  super.layoutSubviews()
  yoga.applyLayout(preservingOrigin: true)
}

核心參數(shù)是 layout.flexWrap = .wrap ,讓視圖布局自動(dòng)換行,再計(jì)算好間距和寬高,這樣就實(shí)現(xiàn)了九宮格的排列效果。

運(yùn)行的效果:


最后編輯于
?著作權(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)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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