class MyCellView: UICollectionViewCell { let theLabel = UILabel() override init(frame: CGRect) { super.init(frame: frame) commonInit() } required init?(coder: NSCoder) { super.init(coder: coder) commonInit() } func commonInit() -> Void { theLabel.translatesAutoresizingMaskIntoConstraints = false theLabel.textAlignment = .center theLabel.backgroundColor = UIColor(white: 0.9, alpha: 1.0) contentView.addSubview(theLabel) let g = contentView.layoutMarginsGuide NSLayoutConstraint.activate([ theLabel.centerXAnchor.constraint(equalTo: g.centerXAnchor), theLabel.centerYAnchor.constraint(equalTo: g.centerYAnchor), ]) } } class CollViewVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout { let cellId: String = "c" let numItems: Int = 100 let colors: [UIColor] = [ .systemRed, .systemBlue, .systemGreen, .systemPink, .systemYellow, .systemTeal ] lazy var navToLabel: UILabel = { let v = UILabel() v.numberOfLines = 0 v.backgroundColor = .green v.text = "Nav To Label: \(numItems) Items (zero-based)" v.translatesAutoresizingMaskIntoConstraints = false return v }() let scrollView: UIScrollView = { let v = UIScrollView() v.translatesAutoresizingMaskIntoConstraints = false return v }() public lazy var myCollection : UICollectionView = { let routine = UICollectionView(frame: CGRect.zero, collectionViewLayout: UICollectionViewFlowLayout()); let routineLayout = UICollectionViewFlowLayout() routineLayout.scrollDirection = .horizontal routine.collectionViewLayout = routineLayout routine.decelerationRate = UIScrollView.DecelerationRate.fast routine.translatesAutoresizingMaskIntoConstraints = false routine.delegate = self routine.dataSource = self routine.backgroundColor = .clear routine.register(MyCellView.self, forCellWithReuseIdentifier: cellId) routine.isPagingEnabled = true routine.showsHorizontalScrollIndicator = false routine.showsVerticalScrollIndicator = false routine.layer.cornerRadius = 20 routine.layer.masksToBounds = true return routine }() override func viewDidLoad() { super.viewDidLoad() view.addSubview(myCollection) view.addSubview(scrollView) scrollView.addSubview(navToLabel) let cg = scrollView.contentLayoutGuide let fg = scrollView.frameLayoutGuide NSLayoutConstraint.activate([ myCollection.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), myCollection.centerXAnchor.constraint(equalTo: view.safeAreaLayoutGuide.centerXAnchor), myCollection.widthAnchor.constraint(equalTo: view.safeAreaLayoutGuide.widthAnchor, multiplier: 0.9), myCollection.heightAnchor.constraint(equalTo: view.safeAreaLayoutGuide.heightAnchor, multiplier: 0.40), scrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 40.0), scrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -40.0), scrollView.topAnchor.constraint(equalTo: myCollection.bottomAnchor, constant: 40.0), scrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -20.0), navToLabel.topAnchor.constraint(equalTo: cg.topAnchor, constant: 0.0), navToLabel.leadingAnchor.constraint(equalTo: cg.leadingAnchor, constant: 0.0), navToLabel.trailingAnchor.constraint(equalTo: cg.trailingAnchor, constant: 0.0), navToLabel.bottomAnchor.constraint(equalTo: cg.bottomAnchor, constant: 0.0), navToLabel.widthAnchor.constraint(equalTo: fg.widthAnchor, constant: 0.0), ]) } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { return 0 } func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { return CGSize(width: collectionView.frame.width, height: collectionView.frame.height) } func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) { let navigatedTo = Int(targetContentOffset.pointee.x) / Int(myCollection.frame.width) guard let t = navToLabel.text else { return } let str = t + "\n\(targetContentOffset.pointee.x) / \(navigatedTo)" navToLabel.text = str } func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return numItems } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let c = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MyCellView c.contentView.backgroundColor = colors[indexPath.item % colors.count] c.theLabel.text = "\(indexPath.item)" return c } }