UICollectionView didSelectItemAt永远不会触发

时间:2018-07-10 10:34:21

标签: ios swift uicollectionview swift4

在我的VC中,我有一个从底部向上拉的视图。我在viewDidLoad()中设置并添加一个UICollectionView:

//Add and setup the collectionView
collectionView = UICollectionView(frame: view.bounds, collectionViewLayout: flowLayout)
collectionView?.register(PhotoCell.self, forCellWithReuseIdentifier: "photoCell")
collectionView?.delegate = self
collectionView?.dataSource = self
collectionView?.backgroundColor = #colorLiteral(red: 0.9771530032, green: 0.7062081099, blue: 0.1748393774, alpha: 1)
collectionView?.allowsMultipleSelection = false
collectionView?.allowsSelection = true
pullUpView.addSubview(collectionView!)
pullUpView.bringSubview(toFront: collectionView!)

UICollectionView Delegate方法在扩展中,目前与VC位于相同的代码文件中:

//MARK: - Extension CollectionView
extension MapVC: UICollectionViewDelegate, UICollectionViewDataSource {
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "photoCell", for: indexPath) as? PhotoCell {
            let imageFromIndex = imagesArray[indexPath.item]
            let imageView = UIImageView(image: imageFromIndex )
            cell.addSubview(imageView)
            return cell
        } else {
            return PhotoCell()
        }
    }


    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("selected")
        //Create PopVC instance, using storyboard id set in storyboard
        guard let popVC = storyboard?.instantiateViewController(withIdentifier: "popVC") as? PopVC else { return }
        popVC.passedImage = imagesArray[indexPath.row]
        present(popVC, animated: true, completion: nil)
    }

}

问题是当我点击一个单元格时什么也没发生。我已经在didSelectItemAt方法中放入了一条打印语句,但是那条语句永远不会被打印出来。因此,我的单元永远不会被选中,或者至少didSelectItemAt方法永远不会被触发!

经过调试和尝试了几个小时,我看不出有什么问题。任何帮助表示赞赏。也许有人可以打开Github上的mijn项目,看看有什么问题,如果允许的话?

更新: 使用“调试视图层次结构”,我看到一些令人不安的东西:每个photoCell都有多个(很多!)UIImageViews。我认为每个photoCell应该只是一个UIImageView。我不知道是什么原因导致了这种行为?

Debug View Hierarchy

1 个答案:

答案 0 :(得分:0)

我检查了您的代码,有几个问题:

首先,只有在创建像元时,您才需要更改PhotoCell实现,并在类内添加imageView。您的单元未加载XIB,因此您必须在init(frame:)中添加imageView:

class PhotoCell: UICollectionViewCell {

    var photoImageView: UIImageView!

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

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

    private func setupCell() {
        photoImageView = UIImageView()
        addSubview(photoImageView)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        photoImageView.frame = bounds // ensure that imageView size is the same of the cell itself
    }

}

此更改后,您可以通过cellForItem方法进行cell.photoImageView.image = imageFromIndex

didSelect未调用的问题是由于您的pullUpView始终为height = 1而引起的,即使您能够看到collectionView,也不会受到任何触摸。

  • 首先在MapVc中添加pullUpView的高度约束的IBOutlet
  • 创建集合视图时,请确保集合视图的大小与pullUpView相同,以便可以滚动; collectionView = UICollectionView(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: 300), collectionViewLayout: flowLayout)

然后将animateViewUpanimateViewDown更改为此

func animateViewUp() {
    mapViewBottomConstraint.constant = 300
    pullUpViewHeightConstraint.constant = 300 // this will increase the height of pullUpView
    UIView.animate(withDuration: 0.5) {
        self.view.layoutIfNeeded()
    }
}
@objc func animateViewDown() {
    cancelAllSessions()

    //remove previous loaded images and urls
    imagesArray.removeAll()
    imageUrlsArray.removeAll()

    mapViewBottomConstraint.constant = 0
    pullUpViewHeightConstraint.constant = 0 // this will reset height to 0
    UIView.animate(withDuration: 0.5) {
        self.view.layoutIfNeeded()
    }
}

通过所有这些操作,向下滑动手势将不再起作用,因为触摸被收集视图拦截并处理了,您应该手动处理。

但是我建议您更改在线课程,但是我对代码有很多不满意的地方。