基础
这部分参考:原文地址
open var axis: NSLayoutConstraint.Axis // 子控件布局方向(水平或者垂直),也就是下面说的轴方向,
/**
case fill 沿轴方向填充视图.会按照优先级压缩或者拉伸子视图
case fillEqually 沿轴方向使子视图等宽或者等高
case fillProportionally 沿轴方向按照`intrinsic content`的比例压缩或者拉伸
case equalSpacing 沿轴按照优先级压缩或者拉伸子视图,使间隙相等
case equalCentering 沿轴方向子视图中心等分
*/
open var distribution: UIStackView.Distribution // 轴方向的控件布局方式
/**
case fill 垂直于轴方向填充视图
case center 子视图中心和轴线重合
case leading .vertical 情况下使用,垂直于轴方向靠左
case trailing .vertical 情况下使用,垂直于轴方向靠右
case top .horizontal 情况下使用,子视图
public static var bottom: UIStackView.Alignment { get } .horizontal 情况下使用
case firstBaseline .horizontal 情况下使用, 按照第一个子视图的baseline对齐,并保证最高视图底部对齐
case lastBaseline .horizontal 情况下使用, 按照最后一个子视图的baseline对齐,并保证最高视图顶部对齐
*/
open var alignment: UIStackView.Alignment // 非轴方向的控件布局方式
open var spacing: CGFloat // 子控件的最小间距
实用技巧
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
//上部滚动页
let scrollView = UIScrollView()
scrollView.backgroundColor = UIColor.gray
//底部标签
let tabStack = UIStackView()
for i in 0 ..< 4 {
let btn = UIButton()
btn.tag = 200 + i
btn.setTitleColor(UIColor.black, for: UIControl.State.normal)
btn.setTitle("\(i)", for: UIControl.State.normal)
btn.addTarget(self, action: #selector(self.itemTouch(sender:)), for: UIControl.Event.touchUpInside)
tabStack.addArrangedSubview(btn)
}
tabStack.axis = .horizontal
tabStack.alignment = .fill
tabStack.distribution = .fillEqually
tabStack.heightAnchor.constraint(equalToConstant: 60).isActive = true
let stackView = self.safeAreaStackView(arrangedSubviews: [scrollView,tabStack])
stackView.axis = .vertical
stackView.alignment = .fill
stackView.distribution = .fill
}
@objc func itemTouch(sender:UIButton){
print("page = \(sender.tag)")
}
}
extension UIViewController {
public func safeAreaStackView(arrangedSubviews: [UIView]) -> UIStackView {
let isIphoneX = UIScreen.main.bounds.height >= 812 ? true : false
var navigationBarHeight:CGFloat = isIphoneX ? 44 : 20
var tabBarHeight:CGFloat = isIphoneX ? 34 : 0
var noNavigationExists = true
if let navigation = self.navigationController {
noNavigationExists = false
navigationBarHeight = navigationBarHeight + CGFloat(navigation.navigationBar.frame.height)
}
if let tabBarController = self.tabBarController {
tabBarHeight = noNavigationExists ? tabBarHeight : 0
tabBarHeight = tabBarHeight + CGFloat(tabBarController.tabBar.frame.height)
}
let view = UIStackView(arrangedSubviews: arrangedSubviews)
view.translatesAutoresizingMaskIntoConstraints = false
self.view.addSubview(view)
// 创建约束
let constraintArrayH = NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[View]-0-|", options: NSLayoutConstraint.FormatOptions(), metrics: nil, views: ["View":view])
let constraintArrayV = NSLayoutConstraint.constraints(withVisualFormat: "V:|-\(navigationBarHeight)-[View]-\(tabBarHeight)-|", options: NSLayoutConstraint.FormatOptions(), metrics: nil, views: ["View":view])
self.view.addConstraints(constraintArrayH)
self.view.addConstraints(constraintArrayV)
return view
}
}
效果演示: