iOS 框架学习之Yoga(一)

1,440 阅读1分钟

Yoga 初识

Yoga是一种跨平台的布局方案,类似CSS中的盒模型,可以扩展到不同的平台上,下面是用Swift实现的样例

self.view.configureLayout { layout in
            layout.isEnabled = true
            layout.width = YGValue(self.view.bounds.size.width)
            layout.height = YGValue(self.view.bounds.size.height)
            layout.alignItems = YGAlign.center
        }
        
let contentView = UIView()
contentView.backgroundColor = UIColor.lightGray
contentView .configureLayout { layout in
    layout.isEnabled = true
    layout.flexDirection = YGFlexDirection.row
    layout.width = YGValue(320)
    layout.height = YGValue(80)
    layout.marginTop = YGValue(100)
    layout.padding = YGValue(10)
}

let child1 = UIView()
child1.backgroundColor = UIColor.red;
child1.configureLayout { layout in
    layout.isEnabled = true;
    layout.width = YGValue(80);
    layout.marginRight = YGValue(10);
}

let child2 = UIView();
child2.backgroundColor = UIColor.blue;
child2.configureLayout { layout in
    layout.isEnabled = true;
    layout.width = YGValue(80);
    layout.flexGrow = 1;
    layout.height = YGValue(20);
    layout.alignSelf = YGAlign.center;
}

contentView.addSubview(child1)
contentView.addSubview(child2)
self.view.addSubview(contentView)
self.view.yoga .applyLayout(preservingOrigin: true)

布局效果如下:

image.png

Yoga 布局

比如,要实现下列的布局

image.png

其中, 整个View中间有一个red box(large), red box 里面有一个green box(medium),最后有两个 blue box (small)居中。

首先考虑在,整个view下加入red box

view.backgroundColor = .white
view.addSubview(largeBoxView)
view.yoga.applyLayout(preservingOrigin: true)

其中,applyLayout 中如果参数preservingOrigin被设置为false,则父View会从{0, 0}开始布局 其中,largeBoxView的布局如下

let largeBoxView: UIView = {
    let view = UIView()
    view.backgroundColor = .red

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

      layout.width = 300
      layout.height = 300
      layout.alignItems = .center
      layout.justifyContent = .center
    }
return view
}()

可以看到,Yoga可以设置视图的长宽,设置子视图居中等等属性,同理,其他的可以相同的设置,所有的代码如下:

//
//  ViewController.swift
//  YogaExample
//
//  Created by Kevin Hermawan on 27/03/21.
//

import UIKit
import YogaKit

class ViewController: UIViewController {

  override func viewDidLoad() {
    super.viewDidLoad()
    
    navigationItem.title = "Hello, Yoga!"
    
    view.configureLayout { (layout) in
      layout.isEnabled = true
      // Styling
      layout.flex = 1
      layout.alignItems = .center
      layout.justifyContent = .center
    }
    
    view.backgroundColor = .white
    view.addSubview(largeBoxView)
    view.yoga.applyLayout(preservingOrigin: true)

    largeBoxView.addSubview(mediumBoxView)
    largeBoxView.yoga.applyLayout(preservingOrigin: true)

    mediumBoxView.addSubview(small1BoxView)
    mediumBoxView.addSubview(small2BoxView)
    mediumBoxView.yoga.applyLayout(preservingOrigin: true)
  }
  
  let largeBoxView: UIView = {
    let view = UIView()
    view.backgroundColor = .red
    
    view.configureLayout { (layout) in
      layout.isEnabled = true
        
      layout.width = 300
      layout.height = 300
      layout.alignItems = .center
      layout.justifyContent = .center
    }
    
    return view
  }()
  
let mediumBoxView: UIView = {
    let view = UIView()
    view.backgroundColor = .green
    
    view.configureLayout { (layout) in
      layout.isEnabled = true
      
      layout.width = 200
      layout.height = 200
      layout.flexDirection = .column
      layout.alignItems = .center
      layout.justifyContent = .spaceEvenly
    }
    
    return view
  }()
  
let small1BoxView: UIView = {
    let view = UIView()
    view.backgroundColor = .blue
    
    view.configureLayout { (layout) in
      layout.isEnabled = true
      
      layout.width = 50
      layout.height = 50
    }
    
    return view
  }()
  
    let small2BoxView: UIView = {
    let view = UIView()
    view.backgroundColor = .blue
    
    view.configureLayout { (layout) in
      layout.isEnabled = true
      
      layout.width = 50
      layout.height = 50
    }
    
    return view
  }()
}