Skip to content

Instantly share code, notes, and snippets.

@pddkhanh
Created September 25, 2019 16:47
Show Gist options
  • Save pddkhanh/f65a335b531fb1af57d3431c95420792 to your computer and use it in GitHub Desktop.
Save pddkhanh/f65a335b531fb1af57d3431c95420792 to your computer and use it in GitHub Desktop.
Simple custom view that auto wrap subviews to new rows
final class SimpleAutoWrapView: UIView {
private var arrangedSubviews: [UIView] = []
private var calculatedIntrinsicContentSize = CGSize.zero {
didSet {
if oldValue != calculatedIntrinsicContentSize {
invalidateIntrinsicContentSize()
}
}
}
var itemSpacing: CGFloat = 20
var lineSpacing: CGFloat = 10
func addArrangedSubview(_ subview: UIView) {
addSubview(subview)
arrangedSubviews.append(subview)
}
override func layoutSubviews() {
super.layoutSubviews()
let rect = bounds.inset(by: layoutMargins)
print("layoutSubviews: \(rect)")
var origin = rect.origin
var rowHeight: CGFloat = 0
arrangedSubviews.enumerated().forEach { index, subview in
let size = subview.systemLayoutSizeFitting(rect.size)
let isNewRow = (index > 0) && (origin.x + size.width > rect.maxX)
if isNewRow {
origin = CGPoint(x: rect.minX, y: origin.y + rowHeight + lineSpacing)
}
subview.frame = CGRect(origin: origin, size: size)
origin.x += (size.width + itemSpacing)
rowHeight = max(rowHeight, size.height)
}
let viewHeight = origin.y + rowHeight + layoutMargins.bottom
calculatedIntrinsicContentSize = CGSize(width: bounds.width, height: viewHeight)
}
override var intrinsicContentSize: CGSize {
print("intrinsicContentSize \(calculatedIntrinsicContentSize)")
return calculatedIntrinsicContentSize
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment