重学AutoLayout (2) — UIStackView
StackView 的要点
- UIStackView 仅仅一个容器!!!(它本身没有
intrinsic content size
) - UIStackView中不同的
distributions
特色作业的原理不一样!!!(fill & fillEqual 表现是不同的!) - 加入到UIStackView中的元素有必要具有
Intrinsic Content Size
ScrollView中嵌套StackView
其间的几个要害:
- ScrollView的Anchor 配备 ScrollView的 ViewPort
- ScrollView内部的StackView的Anchor也需要 Pin到 ScrollView的巨细
- StackView中的Row有必要有
IntrinsicContentSize
- Row可以强制 horizontal 方向的捆绑 override
IntrinsicContent.width
{
func setupViews() {
navigationItem.title = "Scrollable"
let stackView = makeStackView(withOrientation: .vertical)
let scrollView = makeScrollView()
// ScrollView 内部是 stackView
scrollView.addSubview(stackView)
view.addSubview(scrollView)
for _ in 1...30 {
let row = RowView()
stackView.addArrangedSubview(row)
// 操控内部控件捆绑外部view, 强行拉伸宽度
row.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true
}
// Pinning to the sides of view
stackView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
stackView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
stackView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
stackView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
// Pinning scrollview
scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor).isActive = true
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor).isActive = true
}
}
// 自定义 raow
class RowView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
setupViews()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setupViews() {
let titleLabel = makeLabel(withText: "Gapless Playback")
let onOffSwith = makeSwitch(isOn: true)
addSubview(titleLabel)
addSubview(onOffSwith)
// titleLabel
titleLabel.topAnchor.constraint(equalTo: topAnchor).isActive = true
titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
// offSwitch
onOffSwith.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
onOffSwith.centerYAnchor.constraint(equalTo: titleLabel.centerYAnchor).isActive = true
}
// 内置 Intrinsic ContentSize -> 给StackView 供给参看!!!
override var intrinsicContentSize: CGSize {
return CGSize(width: 200, height: 31)
}
}
StackView的运用总结
-
假设我们Pin一个StackView到某些边距的side时, 留意StackView中内容的变化(与center StackView的效果必定不同)
-
UIStackView处理的方针有必要具有
Intrinsic Size
, 因而假设要引入一些自定义方针, 需要重写IntrinsicContentSize
办法. -
在轴向上,除了
stackView.distribution = .fillEqually
以外, 其他的distribution type
, stackview 运用arrangedViews
的intrinsicContentSize
来核算stack axis的标准!!! (这样我们大约能核算出 StackView 在没有其他的外部捆绑时, 轴向的length).-
fillEqually
会使得一切arrangeViews在轴向上具有相同标准的捆绑!!
-
-
在交叉轴上, 除了
stackView.alignment = .fill
以外, 其他的alignment type
, stackview 也是运用arrangedViews
的intrinsicContentSize
的交叉轴的巨细. (这样我们大约能核算出 StackView 在没有其他的外部捆绑时, 交叉轴向的length).-
.alignment = .fill
时, stack 视图将拉伸其一切处理的视图来匹配其交叉轴中 arrangeViews 的最大的固有标准
-
-
在运用StackView时, 除了处理有效内容往后, 也可以经过Anchor添加一些
StackSpacerView
, 协助我们批改不同arrangeSubviews 之间的距离!!! -
运用StackView时, 假设需要在交叉轴拉伸StackView, 有两种常见的办法, 这样required priority 的Anchor能 Override
Intrinsic Size
的捆绑:- 直接给StackView设置widthAnchor
- 给ArrangeView设置一个交叉轴的Anchor, Anchor 需要在 outside View上.
-
嵌套StackView的设计方案, 一定是从内到外结合CRPCHP!!!! 具体可以参看 Apple官方的
Auto Layout CookBook
下面是一个StackSpacerView
的实例:
// 创立一个 spacerView!!! 专门用于添加控件
public func makeSpacerView(height: CGFloat? = nil) -> UIView {
let spacerView = UIView(frame: .zero)
// 添加它的 heightAchor 并且是 breakable()
if let height = height {
spacerView.heightAnchor.constraint(equalToConstant: height).setActiveBreakable()
}
spacerView.translatesAutoresizingMaskIntoConstraints = false
return spacerView
}
// 这儿的服务, 表明当 priority 是 breakable 服务
public extension NSLayoutConstraint {
@objc
func setActiveBreakable(priority: UILayoutPriority = UILayoutPriority(900)) {
self.priority = priority
isActive = true
}
}
参看
- www.cnblogs.com/tieria/p/45…
- www.jianshu.com/p/633e238b2…
- github.com/HChong3210/…