背景
UIStackView在布局方面有很多优势,能减少很多布局的麻烦,但是自带提供的方法过少,也很难用,这里提供几种好用的扩展方法。充分发挥线性布局的优势。
基础扩展
import UIKit
extension UIStackView {
/// 移除所有子视图
func removeAllArrangedSubviews() {
for subview in arrangedSubviews {
removeArrangedSubview(subview)
subview.removeFromSuperview()
}
}
/// 设置子视图
func setArrangedSubviews(_ views: [UIView]) {
removeAllArrangedSubviews()
views.forEach { view in
addArrangedSubview(view)
}
}
/// 移除隐藏的视图
func removeHiddenArrangedSubviews() {
for subview in arrangedSubviews {
if subview.isHidden {
removeArrangedSubview(subview)
subview.removeFromSuperview()
}else {
// 判断子视图是否为UIStackView, 里面的也移除
if let subStackView = subview as? UIStackView,
subStackView.arrangedSubviews.count > 0 {
subStackView.removeHiddenArrangedSubviews()
// 判断如果没有的话,就将自己移除
if subStackView.arrangedSubviews.count == 0 {
removeArrangedSubview(subStackView)
subStackView.removeFromSuperview()
}
}
}
}
}
}
内部占位视图
由于自带的间距不是很好用,这里提供一种自定义间距的视图,spacing不传为填充,传了则有具体大小。这里学习的是SwiftUI中的布局方式。
// MARK: 内部类
extension UIStackView {
/// 占位视图
func spacingView(_ spacing: CGFloat? = nil) -> SpacingView {
return SpacingView.init(axis, spacing)
}
/// 占位空视图
class SpacingView: UIView {
init(_ axis: NSLayoutConstraint.Axis, _ spacing: CGFloat? = nil) {
super.init(frame: .zero)
if let spacing = spacing {
self.snp.makeConstraints { make in
switch axis {
case .horizontal:
make.width.equalTo(spacing)
case .vertical:
make.height.equalTo(spacing)
}
}
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
}
网友评论