基礎
這部分參考:原文地址
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
}
}
效果演示: