Skip to content

Instantly share code, notes, and snippets.

@bugrym
Created February 18, 2020 12:17
Show Gist options
  • Save bugrym/90f4b67fa63eb691e71c6a80f0df352d to your computer and use it in GitHub Desktop.
Save bugrym/90f4b67fa63eb691e71c6a80f0df352d to your computer and use it in GitHub Desktop.
//
// PaneViewController.swift
// PaneApp
//
// Created by Vladyslav Bugrym on 18.02.2020.
// Copyright © 2020 admin. All rights reserved.
//
import UIKit
class PaneViewController:UIViewController {
private lazy var previewPane:PreviewPane = {
let view = PreviewPane()
view.translatesAutoresizingMaskIntoConstraints = false
return view
}()
override func viewDidLoad() {
super.viewDidLoad()
self.setupView()
self.refreshRandomViews()
}
private func setupView() {
self.view.backgroundColor = #colorLiteral(red: 0.9995340705, green: 0.988355577, blue: 0.4726552367, alpha: 1)
self.view.addSubview(previewPane)
let guide = self.view.layoutMarginsGuide
NSLayoutConstraint.activate([
self.previewPane.leadingAnchor.constraint(equalTo: guide.leadingAnchor),
self.previewPane.trailingAnchor.constraint(equalTo: guide.trailingAnchor),
self.previewPane.centerYAnchor.constraint(equalTo: guide.centerYAnchor)])
}
private let itemCount = 15
private func refreshRandomViews() {
var views = [UIView]()
for count in 0..<itemCount {
let view = UILabel()
view.text = "\(count)"
let size = CGFloat(arc4random_uniform(64)) + 32.0
view.font = UIFont.systemFont(ofSize: size)
view.backgroundColor = (count % 2 == 0) ? #colorLiteral(red: 0.8078431487, green: 0.02745098062, blue: 0.3333333433, alpha: 1) : #colorLiteral(red: 0.4666666687, green: 0.7647058964, blue: 0.2666666806, alpha: 1)
views.append(view)
}
previewPane.show(views)
}
}
class PreviewPane:UIView {
private var overflow = [UIView]()
var spacing:CGFloat = 5.0 {
didSet {
stackView.spacing = spacing
}
}
private lazy var stackView:UIStackView = {
let stackView = UIStackView()
stackView.translatesAutoresizingMaskIntoConstraints = false
stackView.spacing = spacing
stackView.alignment = .center
return stackView
}()
///This replaces any views already in the stack view with the new set of views.
func show(_ items:[UIView]){
stackView.arrangedSubviews.forEach { (view) in
view.removeFromSuperview()
}
items.forEach { (view) in
stackView.addArrangedSubview(view)
}
overflow.removeAll()
//The implementation is equivalent
/**
stackView.arrangedSubviews.forEach {
$0.removeFromSuperview()
}
items.forEach {
stackView.addArrangedSubview($0)
} */
}
override init(frame: CGRect) {
super.init(frame: frame)
self.setupView()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
self.setupView()
}
override func layoutSubviews() {
super.layoutSubviews()
///After we call super.layoutSubviews() the layout engine has up- dated the bounds and center of our subviews based on the views and constraints.
while stackView.bounds.width > bounds.width, let extraView = stackView.arrangedSubviews.last {
extraView.removeFromSuperview()
overflow.insert(extraView, at: 0)
updateConstraintsIfNeeded()
super.layoutSubviews()
}
while let nextItem = overflow.first, stackView.bounds.width + spacing + nextItem.intrinsicContentSize.width <= bounds.width {
stackView.addArrangedSubview(nextItem)
overflow.remove(at: 0)
updateConstraintsIfNeeded()
super.layoutSubviews()
}
}
private func setupView() {
addSubview(stackView)
NSLayoutConstraint.activate([
stackView.centerXAnchor.constraint(equalTo: centerXAnchor),
stackView.topAnchor.constraint(equalTo: topAnchor),
stackView.bottomAnchor.constraint(equalTo: bottomAnchor)])
}
}
@bugrym
Copy link
Author

bugrym commented Feb 18, 2020

Vertical

Horizontal

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment