iOS 中使用 FlexBox 佈局實現圖片九宮格

首發於公衆號前端

在 iOS 中官方支持的佈局方式是 AutoLayout,是一種基於控件之間相互約束關係的自動佈局工具。程序員

官方的 AutoLayout 雖然用起來簡單,可是有兩個很是不方便的地方:swift

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

第1個問題可使用第三方庫來解決,好比 SnapKit(swift)、Masonry(oc)。 性能問題則無解,對於混合佈局的 Cell 若是所有使用自動佈局就會看到很明顯的滑動卡頓。app

對於複雜 Cell 佈局,程序員們爲了追求極致的幀率,通常都採用手寫佈局,幀率是上去了而維護的成本也最高。ide

爲了兼顧易用性和高效率,Facebook 開發並開源了本身的佈局庫:Yoga。工具

Yoga 是 FlexBox 的子集,並無所有實現 FlexBox,可是對於大部分應用場景已經足夠了。佈局

接觸過前端開發的朋友對 FlexBox 佈局必定不陌生,CSS 寫 flex 佈局真的太方便了。性能

FlexBox 是不一樣於 AutoLayout 的佈局方式,FlexBox 是自約束,每一個控件的位置都是相對於自身所在的 Box 相對佈局,這就不存在 AutoLayout 基於控件間約束的耦合。flex

Yoga 是基於手動佈局的方式,這樣效率就很高,並且性能損耗很小,並且使用很簡單,用過 Masonry 的同窗能夠很快上手。spa

使用方法:

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 開啓 yoga 佈局, 在 layoutSubviews 中使用 applyLayout 自動調整佈局。

這和手動佈局的流程是同樣的,能夠看出來 yoga 本質上也是手動佈局,只是不再用手算座標了。

yoga 同時也有很好的易用性,好比要實現一個簡單的九宮格,只須要簡單的設置一下佈局參數。

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)
}
複製代碼

核心參數是 layout.flexWrap = .wrap ,讓視圖佈局自動換行,再計算好間距和寬高,這樣就實現了九宮格的排列效果。

運行的效果:

img

img
相關文章
相關標籤/搜索