Skip to content

Instantly share code, notes, and snippets.

@muizidn
Last active August 10, 2019 02:15
Show Gist options
  • Save muizidn/2e7fdf0b89d1bf19dd2251dbe94b3bc4 to your computer and use it in GitHub Desktop.
Save muizidn/2e7fdf0b89d1bf19dd2251dbe94b3bc4 to your computer and use it in GitHub Desktop.
A Horizontal UICollectionLayout with Dynamic Width Cell
import ViewDSL // https://github.com/muizidn/viewdsl
import TinyConstraint // https://github.com/roberthein/TinyConstraints
import RxSwift // https://github.com/ReactiveX/RxSwift
import RxCocoa // https://github.com/ReactiveX/RxSwift
// The Visual Format Language may not correct!
fileprivate let kHeight: CGFloat = 30.0 // V:|-0-(cell)-0-|
fileprivate let kCellSubviewPadding: CGFloat = 10 // H:|-(10)-(subview)
// If we register multiple cell, make sure the estimated width is 2 * biggest padding in registered cell
fileprivate let kEstimatedWidth: CGFloat = kCellSubviewPadding * 2 // H:|-10-(cellsubview)-10-|
func viewDidLoad() {
// Or you can use this value kEstimatedWidth = 2_777_777 See https://twitter.com/muizidn/status/1157122438649405446
// Create Layout
let layout = UICollectionViewFlowLayout { l in
l.scrollDirection = .horizontal
l.minimumLineSpacing = 0 // H:|cell1|-(0)-|cell2|
l.estimatedItemSize = CGSize(width: kEstimatedWidth, height: kHeight) // This will be applied during layout
l.itemSize = CGSize(width: 50.0, height: 30.0) // Whatever value here, the CollectionView doesn't concern.
}
// Create CollectionView
let coll = UICollectionView(frame: .zero, collectionViewLayout: layout)
// Our Cell
class DynamicWidthCell: UICollectionViewCell {
class var reuseIdentifier: String { return "\(type(of: self))" }// DynamicWidthCell.Type
let label = UILabel()
override init(frame: CGRect = .zero) {
super.init(frame: frame)
contentView.add(label) { l in
l.topToSuperview(relation: .equalOrGreater)
l.horizontalToSuperview(insets: .horizontal(kCellSubviewPadding))
l.bottomToSuperview(relation: .equalOrLess)
l.centerYToSuperview()
}
}
required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
coll.register(DynamicWidthCell.self, forCellWithReuseIdentifier: DynamicWidthCell.reuseIdentifier)
Observable.just((1...10).map({ $0 }))
.bind(to: coll.rx.items) { (col, idx, item) -> UICollectionViewCell in
let cell = col.dequeueReusableCell(
withReuseIdentifier: DynamicWidthCell.reuseIdentifier,
for: IndexPath(row: idx, section: 0)) as! DynamicWidthCell
cell.backgroundColor = item % 2 == 0 ? .blue : .yellow
cell.label.text = (0...(idx + 10)).map { "\($0)" }.joined()
return cell
}
.disposed(by: self.disposeBag)
view.add(coll) { (v) in
v.backgroundColor = .green
v.height(kHeight) // Must not smaller than estimatedItemSize.height
v.width(300)
v.centerInSuperview()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment