无法在 Collection 视图上获取 indexPath 和选择

Cannot get indexPath and selection on Collection View

我的 collection 视图有问题。我试图选择一个项目的 indexPath 以在点击后显示更多信息,但我无法理解并弄清楚原因。

我尝试允许 collection 查看选择,但没有任何反应。 我还尝试在单元格上添加点击手势,但不知道如何从那里获取 indexPath。 我在另一个 VC 上添加了相同的代码,其中 collection 视图在整个屏幕上,并且它有效(这里,collection 视图是屏幕的一半)。

这是 collection 视图的(更新​​的)代码:

class SearchRunnerVC: UIViewController {

    //MARK: - Objects
    var lastNameTextField       = RSTextField(placeholder: "Nom du coureur", returnKeyType: .next,
                                              keyboardType: .default)
    var firstNameTextField      = RSTextField(placeholder: "Prénom", returnKeyType: .next,
                                              keyboardType: .default)
    var numberTextField         = RSTextField(placeholder: "Numéro de dossard", returnKeyType: .next,
                                              keyboardType: .numberPad)
    var raceTextField           = RSTextField(placeholder: "Course", returnKeyType: .done,
                                              keyboardType: .default)

    var searchButton            = RSButton(backgroundColor: .systemPink, title: "Rechercher")
    var collectionView          : UICollectionView! = nil

    var emptyLabel              = UILabel()

    let hud = JGProgressHUD(style: .dark)

    lazy var textFields         = [lastNameTextField, firstNameTextField, numberTextField, raceTextField]

    //MARK: - Properties
    let padding = CGFloat(20)
    let runnersCollection = Firestore.firestore().collection("Runner")
    var runners = [Runner]()

    //MARK: - Lifecycle Methods
    override func viewDidLoad() {
        super.viewDidLoad()
        setupUI()
    }
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        navigationController?.navigationBar.prefersLargeTitles = true
        title = "Rechercher"
    }
}
extension SearchRunnerVC {
    fileprivate func setupUI() {
        configureSuperView()
        configureTextFields()
        configureCollectionView()
        configureButton()
        configureConstraints()
    }

    fileprivate func configureSuperView() {
        view.backgroundColor = .systemBackground
        let viewTap = UITapGestureRecognizer(target: self, action: #selector(hideKeyboard(_:)))
        view.addGestureRecognizer(viewTap)
    }
    fileprivate func configureConstraints() {
        for textField in textFields {
            view.addSubview(textField)

            textField.leftToSuperview(view.leftAnchor, offset: padding)
            textField.rightToSuperview(view.rightAnchor, offset: -padding)
            textField.height(50)

            textField.delegate = self
        }

        firstNameTextField.topToSuperview(view.safeAreaLayoutGuide.topAnchor, offset: padding, usingSafeArea: true)

        lastNameTextField.topToBottom(of: firstNameTextField, offset: padding)

        numberTextField.topToBottom(of: lastNameTextField, offset: padding)

        raceTextField.topToBottom(of: numberTextField, offset: padding)

        searchButton.topToBottom(of: raceTextField, offset: padding)
        searchButton.leftToSuperview(view.leftAnchor, offset: padding)
        searchButton.rightToSuperview(view.rightAnchor, offset: -padding)
        searchButton.height(50)

        collectionView.topToBottom(of: searchButton, offset: padding)
        collectionView.edgesToSuperview(excluding: .top)
    }
    fileprivate func configureTextFields() {
        firstNameTextField.tag  = 0
        lastNameTextField.tag   = 1
        numberTextField.tag     = 2
        raceTextField.tag       = 3
    }
    fileprivate func configureButton() {
        view.addSubview(searchButton)

        searchButton.addTarget(self, action: #selector(searchRunners), for: .touchUpInside)
    }
    fileprivate func createLayout() -> UICollectionViewLayout {
        let itemSize    = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1.0),
                                                 heightDimension: .fractionalHeight(1.0))
        let item        = NSCollectionLayoutItem(layoutSize: itemSize)


        let groupSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1),
                                               heightDimension: .estimated(100))
        let group   = NSCollectionLayoutGroup.horizontal(layoutSize: groupSize, subitem: item, count: 2)
        let spacing = CGFloat(10)
        group.interItemSpacing = .fixed(spacing)


        let section = NSCollectionLayoutSection(group: group)
        section.interGroupSpacing = spacing

        let padding = CGFloat(10)
        section.contentInsets = NSDirectionalEdgeInsets(top: 0, leading: padding, bottom: 0, trailing: padding)

        let headerSize = NSCollectionLayoutSize(widthDimension: .fractionalWidth(1), heightDimension: .estimated(80))
        let header     = NSCollectionLayoutBoundarySupplementaryItem(layoutSize: headerSize, elementKind: UICollectionView.elementKindSectionHeader, alignment: .top)

        section.boundarySupplementaryItems = [header]

        let layout = UICollectionViewCompositionalLayout(section: section)
        return layout
    }
    fileprivate func configureCollectionView() {
        collectionView = UICollectionView(frame: .zero, collectionViewLayout: createLayout())

        collectionView.autoresizingMask = [.flexibleHeight]
        collectionView.backgroundColor  = .systemBackground

        collectionView.delegate     = self
        collectionView.dataSource   = self

        collectionView.register(RunnerCell.self, forCellWithReuseIdentifier: RunnerCell.reuseID)
        collectionView.register(Header.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: Header.reuseID)

        view.addSubview(collectionView)
    }
}

extension SearchRunnerVC : UICollectionViewDelegate, UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return runners.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: RunnerCell.reuseID, for: indexPath) as? RunnerCell else { fatalError("Unable to dequeue runner cell")}

        cell.configure(runner: runners[indexPath.row])

        return cell
    }


    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: Header.reuseID, for: indexPath) as? Header else { fatalError("Unable to dequeue header")}
        header.title.text = "Résultats"
        header.seeButton.addTarget(self, action: #selector(seeAllTapped), for: .touchUpInside)
        header.separator.alpha = 0
        header.backgroundColor = collectionView.backgroundColor
        return header
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print(indexPath.item)
    }
}

不要在单元格上使用点击手势,因为

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath)

完全符合您的期望。问题可能出在您的 collectionView configuration/setup 中。你能展示完整的 ViewController 代码吗?

您的问题似乎与您要添加到 configureSuperView() 中的 视图UITapGestureRecognizer 有关。通常会触发 collectionView didSelectItemAt... 委托函数的触摸被发送到手势识别器的处理程序,即 hideKeyboard()

view.addGestureRecognizer(viewTap) 注释行,您的代码将起作用。如果是这样,我也可以帮助您实现 hideKeyboard 功能,请告诉我。