class SingleLabelCell: UICollectionViewCell { static let identifier: String = "singleLabelCell" let theLabel: UILabel = { let v = UILabel() v.font = .systemFont(ofSize: 14.0, weight: .light) v.textAlignment = .center v.numberOfLines = 0 v.backgroundColor = UIColor(white: 0.9, alpha: 1.0) v.layer.cornerRadius = 12 v.clipsToBounds = true v.translatesAutoresizingMaskIntoConstraints = false return v }() override init(frame: CGRect) { super.init(frame: frame) commonInit() } required init?(coder: NSCoder) { super.init(coder: coder) commonInit() } func commonInit() -> Void { contentView.addSubview(theLabel) let g = contentView NSLayoutConstraint.activate([ theLabel.topAnchor.constraint(equalTo: g.topAnchor, constant: 4.0), theLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 4.0), theLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -4.0), theLabel.bottomAnchor.constraint(equalTo: g.bottomAnchor, constant: -4.0), ]) // during development, so we can see the cell framing contentView.backgroundColor = .systemYellow } } class SampleViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate { var collectionCarousel: UICollectionView! override func viewDidLoad() { super.viewDidLoad() view.backgroundColor = .systemBackground // horizontal flow layout let fl = UICollectionViewFlowLayout() fl.scrollDirection = .horizontal fl.minimumLineSpacing = 8 fl.minimumInteritemSpacing = 8 fl.itemSize = .init(width: 80.0, height: 40.0) collectionCarousel = UICollectionView(frame: .zero, collectionViewLayout: fl) collectionCarousel.translatesAutoresizingMaskIntoConstraints = false view.addSubview(collectionCarousel) let g = view.safeAreaLayoutGuide NSLayoutConstraint.activate([ // constrain collectionView to Top/Leading/Trailing of safe-area collectionCarousel.topAnchor.constraint(equalTo: g.topAnchor, constant: 0.0), collectionCarousel.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 0.0), collectionCarousel.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: 0.0), collectionCarousel.heightAnchor.constraint(equalToConstant: 50.0), ]) collectionCarousel.register(SingleLabelCell.self, forCellWithReuseIdentifier: SingleLabelCell.identifier) collectionCarousel.dataSource = self collectionCarousel.delegate = self // so we can see the collection view framing collectionCarousel.backgroundColor = UIColor(white: 0.9, alpha: 1.0) } var bFirstLayout: Bool = true override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() // if this is the first layout of this controller, // center section 8 horizontally (but not animated) if bFirstLayout { bFirstLayout = false selectItemAndScroll(8, animated: false) } } func numberOfSections(in collectionView: UICollectionView) -> Int { return 11 } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return 1 } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let c = collectionView.dequeueReusableCell(withReuseIdentifier: SingleLabelCell.identifier, for: indexPath) as! SingleLabelCell c.theLabel.text = "\(indexPath.section)" return c } func selectItemAndScroll(_ setIndex: Int = 0, animated: Bool ) { let startIndexPath = IndexPath(item: 0, section: setIndex) collectionCarousel.selectItem(at: startIndexPath, animated: animated, scrollPosition: .centeredHorizontally) } }