【问题标题】:UICollectionView didSelectItemAt never triggersUICollectionView didSelectItemAt 从不触发
【发布时间】:2018-12-18 04:03:25
【问题描述】:

在我的 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 项目,看看有什么问题,如果允许的话?

更新: 使用 Debug View Hierarchy,我看到一些令人不安的事情:每个 photoCell 都有多个(很多!)UIImageViews。我认为每个 photoCell 应该只有一个 UIImageView。我不知道是什么导致了这种行为?

Debug View Hierarchy

【问题讨论】:

  • 如果你长按,那么它会起作用吗?
  • github的链接在哪里
  • 长按也不行,模拟器不行,物理设备不行
  • 这里是 Github 链接github.com/Gakkienl/Pixel-City
  • 由于缺少 podfile 和依赖项,您在 github 上的项目无法编译

标签: ios swift uicollectionview swift4


【解决方案1】:

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

首先,您必须更改您的 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总是高度=1,即使你能看到collectionView,它也不会收到任何触摸。

  • 首先在你的 MapVc 中添加 pullUpView 高度约束的 IBOutlet
  • 在创建collection view时,确保collection view的大小和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()
    }
}

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

不过我建议你改在线课程,这段代码有很多我不喜欢的地方。

【讨论】:

  • 谢谢。我会去实施你指出的改变!
  • pullUpView 高度限制确实是罪魁祸首!我为此添加了一个插座并更改了 animateViewUp() 中的高度。现在就可以了,但我也将实施您的建议。老实说,我很好奇你不喜欢课程代码的什么地方!
  • 是的,在这段代码的(许多)问题中,单元格不能“点击”的原因是pullUpView 的高度限制。与其将其添加为 IBOutlet 并对其进行更改,不如删除 Height 约束并将 0 的 Bottom 约束添加到安全区域。这将允许自动布局根据需要自动更改 pullUpView 的高度(如果您决定调整集合视图的区域,则无需进行多项更改)。
  • 我同意@DonMag,但是在 cellForItem 中添加子视图并不好,因为每次需要显示单元格时都会调用它;我不喜欢混合自动布局和手动设置视图的位置和大小;应用于视图的 panGesture 不正确,因为它不起作用:collectionView 滚动将阻止平移手势触发(但为此,也许课程会教你如何处理)
  • @Gakkie 如果对您有帮助,请投票/设置为最佳答案:D
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多