Swift 3:能够在collectionViewCell后面点击视图吗?

时间:2017-03-30 12:17:10

标签: swift swift3 uicollectionview uicollectionviewcell

我正在开发一个我的应用程序中的新功能,我希望用户拥有一个图像,然后能够在该图像上滑动一个collectionView,添加“过滤器”。我遇到的问题是我希望用户仍然能够与图像进行交互,但它位于collectionView的后面。如果我将collectionViews inUsersInteractionEnabled设置为false,那么我当然不能使用collectionView。我想要一个类似于Snapchats“滚动过滤器”功能的功能。任何帮助将受到高度赞赏。感谢你们。代码如下:

import UIKit

class FirstCell: UICollectionViewCell {

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

    func setupViews() {
        backgroundColor = .clear
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class SecondCell: UICollectionViewCell {

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

    let cellView: UIView = {
        let view = UIView()
        view.backgroundColor = .red
        view.alpha = 0.25
        return view
    }()

    func setupViews() {
        backgroundColor = .clear
        addSubview(cellView)

        cellView.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.frame.height)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class SecondController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.minimumLineSpacing = 0
        layout.minimumInteritemSpacing = 0
        layout.scrollDirection = .horizontal
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .clear
        cv.dataSource = self
        cv.delegate = self
        cv.translatesAutoresizingMaskIntoConstraints = false
        cv.isPagingEnabled = true
        return cv
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView.register(FirstCell.self, forCellWithReuseIdentifier: "firstCell")
        collectionView.register(SecondCell.self, forCellWithReuseIdentifier: "secondCell")

        view.backgroundColor = .white

        setupViews()
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: view.frame.width, height: view.frame.height)
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 2
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

        if indexPath.item == 0 {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "firstCell", for: indexPath) as! FirstCell
            return cell
        } else {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "secondCell", for: indexPath) as! SecondCell
            return cell
        }
    }

    lazy var imageView: UIImageView = {
        let iv = UIImageView()
        let image = UIImage(named: "img")
        iv.image = image
        iv.contentMode = .scaleAspectFill
        iv.translatesAutoresizingMaskIntoConstraints = false
        iv.isUserInteractionEnabled = true
        iv.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
        return iv
    }()

    func handleTap() {
        print(123)
    }

    func setupViews() {
        view.addSubview(imageView)
        view.addSubview(collectionView)

        imageView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        imageView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        imageView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        imageView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true

        collectionView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        collectionView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        collectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
        collectionView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
    }

}

1 个答案:

答案 0 :(得分:0)

hitTest(_::)个方法可以在任何UIView子类中覆盖,您可以在自定义UICollectionView子类中实现这些方法,并将其从中转发到任何其他视图(在您的情况下集合视图背后的图像)。

override func hitTest(_ point: CGPoint,
                               with event: UIEvent?) -> UIView? {

    let hitView = super.hitTest(point, with: event)

    if self.parentViewController.forwardTapToImageIfNeeded(point) {
        return nil
    }

    return hitView
}

parentViewController是对SecondController实例的引用,forwardTapToImageIfNeeded(_)实例应具有func forwardTapToImageIfNeeded(_ p: CGPoint) -> Bool { /* Convert point to local coordinates */ let pointInSuperView = self.convert(p, from: collectionView) /* Check if tap is on top of the image frame */ if imageBehindCollection.frame.contains(pointInSuperView) { // Forward tap to the image `imageBehindCollection` return true } return false } 功能,以检查用户的点击是否在图像框的顶部,如果是 - 自动通过点击它的事件。

show

注意:我没有自己测试这个特定的代码,所以在Xcode中可能需要一些修复。