Last active
August 10, 2019 02:15
-
-
Save muizidn/2e7fdf0b89d1bf19dd2251dbe94b3bc4 to your computer and use it in GitHub Desktop.
A Horizontal UICollectionLayout with Dynamic Width Cell
This file contains hidden or 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 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