Forked from NachoSoto/FullWidthSelfSizingCollectionView.swift
Created
March 7, 2018 12:28
-
-
Save dehlen/d6004b03f9cb76a5b4b7cec4343b94c7 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import UIKit | |
import Cartography // https://github.com/robb/Cartography | |
/** | |
This is an example of self sizing `UICollectionView` cells using AutoLayout, | |
where the width of cells is always the width of the parent, to mimic `UITableView`. | |
*/ | |
fileprivate let items: [String] = (0..<100) | |
.map { _ in Lorem.sentences(Int.random(min: 1, max: 8)) } // Using https://github.com/lukaskubanek/LoremSwiftum/blob/master/Sources/LoremSwiftum.swift | |
final class ViewController: UIViewController { | |
override func loadView() { | |
self.view = self.customView | |
} | |
private lazy var customView = View() | |
} | |
private final class View: UIView { | |
init() { | |
self.collectionView = UICollectionView(frame: .zero, | |
collectionViewLayout: self.layout) | |
super.init(frame: .zero) | |
self.collectionView.register(Cell.self, forCellWithReuseIdentifier: View.reuseIdentifier) | |
self.collectionView.dataSource = self | |
self.addSubview(self.collectionView) | |
constrain(self.collectionView, self) { view, superview in | |
view.edges == superview.edges | |
} | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
private let collectionView: UICollectionView | |
private let layout: UICollectionViewFlowLayout = { | |
let layout = UICollectionViewFlowLayout() | |
layout.scrollDirection = .vertical | |
layout.sectionInset = .zero | |
layout.estimatedItemSize = CGSize(width: 100, height: 100) | |
return layout | |
}() | |
var previousSize: CGSize? | |
override func layoutSubviews() { | |
super.layoutSubviews() | |
if let previousSize = self.previousSize, previousSize != .zero, previousSize != self.bounds.size { | |
// Need to invalidate layout AND reload data to make rotation work | |
self.layout.invalidateLayout() | |
self.collectionView.reloadData() | |
} | |
self.previousSize = self.bounds.size | |
} | |
fileprivate static let reuseIdentifier = "cell" | |
} | |
extension View: UICollectionViewDataSource { | |
func numberOfSections(in collectionView: UICollectionView) -> Int { | |
return 1 | |
} | |
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { | |
return items.count | |
} | |
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { | |
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: View.reuseIdentifier, for: indexPath) as! Cell | |
cell.text = items[indexPath.row] | |
cell.width = collectionView.bounds.size.width | |
return cell | |
} | |
} | |
private final class Cell: UICollectionViewCell { | |
override init(frame: CGRect) { | |
super.init(frame: frame) | |
self.contentView.addSubview(self.label) | |
self.contentView.backgroundColor = .orange | |
constrain(self.label, self.contentView, self) { label, superview, cell in | |
label.edges == inset(superview.edges, 10) | |
superview.center == cell.center | |
} | |
} | |
required init?(coder aDecoder: NSCoder) { | |
fatalError("init(coder:) has not been implemented") | |
} | |
var text: String = "" { | |
didSet { | |
self.label.text = self.text | |
self.setNeedsLayout() | |
} | |
} | |
var width: CGFloat = 0 { | |
didSet { | |
self.widthGroup = constrain(self.contentView, replace: self.widthGroup) { view in | |
view.width == self.width | |
} | |
} | |
} | |
private var widthGroup: ConstraintGroup! | |
private let label: UILabel = { | |
let label = UILabel() | |
label.numberOfLines = 0 | |
label.textColor = .white | |
label.font = UIFont.preferredFont(forTextStyle: .body) | |
return label | |
}() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment