Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // ViewController.swift
- // StackCollectionView
- //
- // Created by Krzysztof Babis on 20/03/2020.
- // Copyright © 2020 Krzysztof Babis. All rights reserved.
- //
- import UIKit
- import SnapKit
- class ViewController: UIViewController {
- private var collectionView: UICollectionView!
- override func viewDidLoad() {
- super.viewDidLoad()
- initializeCollectionView()
- }
- override func viewDidAppear(_ animated: Bool) {
- super.viewDidAppear(true)
- //collectionView.scrollToItem(at: IndexPath(item: 10, section: 0), at: .centeredVertically, animated: true)
- }
- private func initializeCollectionView() {
- collectionView = UICollectionView(frame: .zero, collectionViewLayout: StickyCollectionViewFlowLayout())
- collectionView.backgroundColor = .yellow
- collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
- collectionView.dataSource = self
- collectionView.delegate = self
- view.addSubview(collectionView)
- collectionView.snp.makeConstraints { (make) in
- make.left.right.bottom.equalTo(view.safeAreaLayoutGuide)
- make.height.equalToSuperview().multipliedBy(0.3)
- }
- }
- }
- extension ViewController: UICollectionViewDelegateFlowLayout {
- func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
- return CGSize(width: UIScreen.main.bounds.width * 0.8, height: UIScreen.main.bounds.height * 0.25)
- }
- }
- extension ViewController: UICollectionViewDataSource {
- func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
- return 10
- }
- func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
- let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
- let label = UILabel(frame: cell.bounds)
- cell.layer.borderWidth = 2.0
- cell.layer.borderColor = UIColor.black.cgColor
- cell.backgroundColor = .red
- label.text = "\(indexPath.row)"
- label.textAlignment = .center
- cell.addSubview(label)
- return cell
- }
- }
- final class StickyCollectionViewFlowLayout: UICollectionViewFlowLayout {
- private let overlap: CGFloat
- private let scaleMultiplier: CGFloat?
- init(overlap: CGFloat = 10.0, scaleMultiplier: CGFloat = 0.06) {
- self.overlap = overlap
- self.scaleMultiplier = scaleMultiplier
- super.init()
- }
- required init?(coder: NSCoder) {
- fatalError("init(coder:) has not been implemented")
- }
- override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
- guard let superLayoutAttributes = super.layoutAttributesForElements(in: rect) else { return nil }
- let items = NSArray(array: superLayoutAttributes, copyItems: true)
- var headerAttributes: UICollectionViewLayoutAttributes?
- for item in items {
- guard let attributes = item as? UICollectionViewLayoutAttributes else { continue }
- if attributes.representedElementKind == UICollectionView.elementKindSectionHeader {
- headerAttributes = attributes
- } else {
- self.updateCellAttributes(attributes, headerAttributes: headerAttributes)
- }
- }
- return items as? [UICollectionViewLayoutAttributes]
- }
- func updateCellAttributes(_ attributes: UICollectionViewLayoutAttributes, headerAttributes: UICollectionViewLayoutAttributes?) {
- guard let collectionView = collectionView else { return }
- let minY = collectionView.bounds.minY + collectionView.contentInset.top
- var maxY = attributes.frame.origin.y
- if let headerAttributes = headerAttributes {
- maxY -= headerAttributes.bounds.height
- }
- let finalY = max(minY, maxY)
- var origin = attributes.frame.origin
- if let scaleMultiplier = scaleMultiplier {
- let deltaY = (finalY - origin.y) / attributes.frame.height
- let scale = 1 - deltaY * scaleMultiplier
- attributes.transform = CGAffineTransform(scaleX: scale, y: scale)
- }
- origin.y = finalY + CGFloat(attributes.indexPath.row) * overlap
- attributes.frame = CGRect(origin: origin, size: attributes.frame.size)
- attributes.zIndex = attributes.indexPath.row
- }
- override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
- return true
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement