Files
Attractor/App/Utilities/StackView.swift

93 lines
2.6 KiB
Swift
Raw Normal View History

2020-09-22 15:37:13 -07:00
//
// StackView.swift
// App
//
// Created by James Magahern on 9/22/20.
//
import UIKit
class StackView: UIView
{
var arrangedSubviews: [UIView] = []
{ didSet { setNeedsLayout() } }
var layoutDimension: UIAxis = .vertical
convenience init(dimension: UIAxis) {
self.init(frame: .zero)
self.layoutDimension = dimension
}
// Convenience
public func addArrangedSubview(_ view: UIView) {
addSubview(view)
arrangedSubviews.append(view)
setNeedsLayout()
}
public func removeArrangedSubview(_ view: UIView) {
if view.superview == self {
view.removeFromSuperview()
}
arrangedSubviews.removeAll { $0 == view }
setNeedsLayout()
}
public func removeAllArrangedSubviews() {
arrangedSubviews.forEach { $0.removeFromSuperview() }
arrangedSubviews.removeAll()
setNeedsLayout()
}
override func sizeThatFits(_ containerSize: CGSize) -> CGSize {
var size: CGSize = .zero
if layoutDimension == .horizontal {
size.height = containerSize.height
} else {
size.width = containerSize.width
}
var spaceRemaining = containerSize
for view in arrangedSubviews {
let viewSize = view.sizeThatFits(spaceRemaining)
if layoutDimension == .horizontal {
size.width += viewSize.width
spaceRemaining.width -= viewSize.width
} else {
size.height += viewSize.height
spaceRemaining.height -= viewSize.height
}
}
return size
}
override func layoutSubviews() {
super.layoutSubviews()
var origin: CGPoint = CGPoint(x: safeAreaInsets.left, y: safeAreaInsets.top)
var spaceRemaining = bounds.size
for view in arrangedSubviews {
var viewSize = view.sizeThatFits(spaceRemaining)
var offset: CGPoint = .zero
if layoutDimension == .horizontal {
offset.x = viewSize.width
viewSize.height = bounds.height
spaceRemaining.width -= viewSize.width
} else {
offset.y = viewSize.height
viewSize.width = bounds.width
spaceRemaining.height -= viewSize.height
}
view.frame = CGRect(origin: origin, size: viewSize)
origin.x += offset.x
origin.y += offset.y
}
}
}