尝试创建一个集合视图在滚动时滑过另一个集合视图的效果

Ave*_*ine 5 ios uicollectionview swift

我有两个集合视图,在我的 ViewController 中一个层叠在另一个之上。顶部的集合视图是水平滚动的集合视图,而下方的集合视图垂直滚动。我正在尝试创建一种效果,其中滚动下部集合视图将使其向上移动以覆盖上部集合视图,就像一种视差效果。

我设法通过将两个视图固定到屏幕顶部并在滚动时修改下部集合视图的内容插入来获得效果,但是这种方法意味着我无法与上部集合视图进行交互,即使它暴露出来也是如此。我正在寻找对此方法的修改,或者一种新方法,它可以让我保留这种效果并与上层集合视图进行交互。关于如何解决这个问题的任何建议?谢谢。

我目前拥有的代码(或多或少):

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentInset.top = max(0, min(tendToSoon.frame.height, -scrollView.contentOffset.y))
}
Run Code Online (Sandbox Code Playgroud)

Gif 示例

展开:

未滚动

轻微滚动:

稍微滚动

更多滚动:

更多滚动

Raj*_*r R 5

在视图控制器中添加两个 collectionview 并设置contentInset.top为第一个 colletionview 的高度。并contentOffset.y减去 的值contentInset.top。而override point(inside:with:)并返回true仅当Y值大于0。

确保第二个 collectionview 的背景颜色清晰。

滚动集合视图

class ViewController: UIViewController {

    let topCollectionTitle = UILabel()
    let topCollectionView = UICollectionView(frame: .zero, collectionViewLayout: UICollectionViewLayout())
    let bottomCollectionView = BottomCollectionView(frame: .zero, collectionViewLayout: UICollectionViewLayout())

    override func viewDidLoad() {
        super.viewDidLoad()

        self.view.backgroundColor = .white

        topCollectionTitle.textAlignment = .center
        topCollectionTitle.text = "Top Collectionview"
        topCollectionTitle.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(topCollectionTitle)

        let topLayout = UICollectionViewFlowLayout()
        topLayout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        topLayout.itemSize = CGSize(width: self.view.bounds.width / 5, height: 150)
        topLayout.scrollDirection = .horizontal
        topLayout.minimumLineSpacing = 0
        topLayout.minimumInteritemSpacing = 0
        topCollectionView.contentInsetAdjustmentBehavior = .never
        topCollectionView.collectionViewLayout = topLayout
        topCollectionView.backgroundColor = .white
        topCollectionView.register(CellHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "CellHeader")

        topCollectionView.register(ImgCell.self, forCellWithReuseIdentifier: "ImgCell")
        topCollectionView.delegate = self
        topCollectionView.dataSource = self
        topCollectionView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(topCollectionView)

        let bottomLayout = UICollectionViewFlowLayout()
        bottomLayout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        bottomLayout.itemSize = CGSize(width: self.view.bounds.width / 2, height: 150)
        bottomLayout.scrollDirection = .vertical
        bottomLayout.minimumLineSpacing = 0
        bottomLayout.minimumInteritemSpacing = 0
        bottomLayout.headerReferenceSize = CGSize(width: 50, height: 50)
        bottomCollectionView.collectionViewLayout = bottomLayout
        bottomCollectionView.backgroundColor = .clear
        bottomCollectionView.register(CellHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "CellHeader")
        bottomCollectionView.register(ImgCell.self, forCellWithReuseIdentifier: "ImgCell")
        bottomCollectionView.delegate = self
        bottomCollectionView.dataSource = self
        bottomCollectionView.translatesAutoresizingMaskIntoConstraints = false
        self.view.addSubview(bottomCollectionView)

        bottomCollectionView.contentInset.top = 200
        bottomCollectionView.contentOffset.y = -200

        topCollectionTitle.topAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.topAnchor).isActive = true

        self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[topCollectionView]|", options: [], metrics: nil, views: ["topCollectionView":topCollectionView]))
        self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:[topCollectionTitle(30)][topCollectionView(200)]", options: [], metrics: nil, views: ["topCollectionView":topCollectionView,"topCollectionTitle":topCollectionTitle]))
        self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-(10)-[topCollectionTitle]|", options: [], metrics: nil, views: ["topCollectionTitle":topCollectionTitle]))
        self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[bottomCollectionView]|", options: [], metrics: nil, views: ["bottomCollectionView":bottomCollectionView]))
        self.view.addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[bottomCollectionView]|", options: [], metrics: nil, views: ["bottomCollectionView":bottomCollectionView]))

    }
}
extension ViewController: UICollectionViewDelegate {

}
extension ViewController: UICollectionViewDataSource {
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 25
    }
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ImgCell", for: indexPath) as? ImgCell ?? ImgCell()
        cell.imgView.backgroundColor = .red
        return cell
    }
    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        if kind == UICollectionView.elementKindSectionHeader {
            let header = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "CellHeader", for: indexPath) as? CellHeader
            if collectionView == bottomCollectionView {
                header?.titleLbl.text = "Bottom CollectionView"
            }
            return header!
        }
        return UICollectionReusableView()
    }
}

class ImgCell: UICollectionViewCell {

    let imgView = UIImageView()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupViews()
    }
    func setupViews() {
        backgroundColor = .white

        imgView.layer.cornerRadius = 5.0
        imgView.layer.masksToBounds = true
        imgView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(imgView)
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|-(5)-[imgView]-(5)-|", options: [], metrics: nil, views: ["imgView":imgView]))
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|-(5)-[imgView]-(5)-|", options: [], metrics: nil, views: ["imgView":imgView]))
    }
}
class CellHeader: UICollectionReusableView {

    let titleLbl = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)
        setupViews()
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        setupViews()
    }
    func setupViews() {
        backgroundColor = .white

        titleLbl.textAlignment = .center
        titleLbl.translatesAutoresizingMaskIntoConstraints = false
        addSubview(titleLbl)

        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[titleLbl]|", options: [], metrics: nil, views: ["titleLbl":titleLbl]))
        addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "V:|[titleLbl]|", options: [], metrics: nil, views: ["titleLbl":titleLbl]))
    }
}
class BottomCollectionView:UICollectionView {
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        return point.y > 0
    }
}
Run Code Online (Sandbox Code Playgroud)