简体   繁体   English

为什么 didSelect function 仅适用于视图 controller 中的两个集合视图之一?

[英]Why didSelect function only works for one of two collection views in a view controller?

I have two collection views (restaurantCollectionView and filterCollectionView) and I want to update the restaurantCollectionView after selecting a filterCollectionView cell.我有两个集合视图(restaurantCollectionView 和 filterCollectionView),我想在选择 filterCollectionView 单元格后更新 restaurantCollectionView。 I have tried to use didSelected function.我曾尝试使用didSelected function。 However, it seems that the function always takes restaurantCollectionView, not filterCollectionView, as the input.但是,function 似乎总是将 restaurantCollectionView 而不是 filterCollectionView 作为输入。 How can I achieve filtering using these two collection views?如何使用这两个集合视图实现过滤?

The following is my current code.以下是我当前的代码。 I left out some irrelevant setup codes such as creating Restaurant and Filter objects.我省略了一些不相关的设置代码,例如创建 Restaurant 和 Filter 对象。

class ViewController: UIViewController {

    var filterCollectionView: UICollectionView!
    var restaurantCollectionView: UICollectionView!

    var filters = [Filter]()

    var restaurants1 = [Restaurant]()
    var restaurants2 = [Restaurant]()

    override func viewDidLoad() {
        super.viewDidLoad()

        title = "My Restaurants"
        view.backgroundColor = .lightGray
        navigationController?.navigationBar.barTintColor = UIColor(displayP3Red: 0.2, green: 0.3, blue: 0.8, alpha: 0.7)
        navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]

        filters = [mexican, american, asian, greek, fastfood, seafood, breakast, lunch, dinner, cheap, acceptable]
        restaurants1 = [chipotle, chick, pokeland, ctb, fourseasons, aladdins]
        restaurants2 = [chipotle, chick, pokeland, ctb, fourseasons, aladdins]

        let filterLayout = UICollectionViewFlowLayout()
        filterLayout.scrollDirection = .horizontal
        filterLayout.minimumInteritemSpacing = padding
        filterLayout.minimumLineSpacing = padding

        let restaurantLayout = UICollectionViewFlowLayout()
        restaurantLayout.scrollDirection = .vertical
        restaurantLayout.minimumInteritemSpacing = 5
        restaurantLayout.minimumLineSpacing = padding

        filterCollectionView = UICollectionView(frame: .zero, collectionViewLayout: filterLayout)
        filterCollectionView.translatesAutoresizingMaskIntoConstraints = false
        filterCollectionView.backgroundColor = .lightGray
        filterCollectionView.register(FilterCollectionViewCell.self, forCellWithReuseIdentifier: filterReuseIdentifier)
        filterCollectionView.dataSource = self
        filterCollectionView.delegate = self
        view.addSubview(filterCollectionView)

        restaurantCollectionView = UICollectionView(frame: .zero, collectionViewLayout: restaurantLayout)
        restaurantCollectionView.translatesAutoresizingMaskIntoConstraints = false
        restaurantCollectionView.backgroundColor = .lightGray
        restaurantCollectionView.register(RestaurantCollectionViewCell.self, forCellWithReuseIdentifier: restaurantReuseIdentifier)
        restaurantCollectionView.dataSource = self
        restaurantCollectionView.delegate = self
        view.addSubview(restaurantCollectionView)


        setupConstraints()

    }

    func setupConstraints() {

        NSLayoutConstraint.activate([
            filterCollectionView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 2),
            filterCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: padding),
            filterCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -padding),
            filterCollectionView.heightAnchor.constraint(equalToConstant: 70)
        ])

        NSLayoutConstraint.activate([
            restaurantCollectionView.topAnchor.constraint(equalTo: filterCollectionView.bottomAnchor, constant: 2),
            restaurantCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
            restaurantCollectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            restaurantCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -10)
        ])
    }

}

extension ViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if collectionView == self.filterCollectionView{
            return filters.count
        }
        else {
            return restaurants2.count
        }
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if collectionView == self.filterCollectionView {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: filterReuseIdentifier, for: indexPath) as! FilterCollectionViewCell

            cell.backgroundColor = .white
            cell.filterName.setTitleColor(UIColor(displayP3Red: 0.2, green: 0.3, blue: 0.8, alpha: 0.7), for: .normal)
            cell.configure(filter: filters[indexPath.item])
            cell.filterName.addTarget(self, action: #selector(changeColor), for: .touchUpInside)
            return cell
        }
        else {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: restaurantReuseIdentifier, for: indexPath) as! RestaurantCollectionViewCell

            cell.configure(restaurant: restaurants2[indexPath.item])
            return cell
        }
    }

    @objc func changeColor(sender: Any) {
        if let button = sender as? UIButton {
            let point: CGPoint = button.convert(.zero, to: filterCollectionView)
            if let indexPath = filterCollectionView.indexPathForItem(at: point) {
                let cell = filterCollectionView.cellForItem(at: indexPath) as! FilterCollectionViewCell
                if cell.backgroundColor == UIColor.white{
                    cell.backgroundColor = UIColor(displayP3Red: 0.2, green: 0.3, blue: 0.8, alpha: 0.7)
                    cell.filterName.setTitleColor(.white, for: .normal)
                }
                else {
                    cell.backgroundColor = UIColor.white
                    cell.filterName.setTitleColor(UIColor(displayP3Red: 0.2, green: 0.3, blue: 0.8, alpha: 0.7), for: .normal)
                }
            }
        }

    }

}

extension ViewController: UICollectionViewDelegateFlowLayout {

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        if collectionView == self.filterCollectionView{
            return CGSize(width: 100, height: 50)
        }
        else {
            let width = (collectionView.frame.width - 2 * padding) / 2.0
            let height = (collectionView.frame.height - 3 * padding) / 4.0
            return CGSize(width: width, height: height)
        }
    }

}

extension ViewController: UICollectionViewDelegate {

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        if collectionView == self.filterCollectionView {
            let requirement = filters[indexPath.item].filterName

            restaurants2 = restaurants1.filter({$0.cuisine.contains(requirement) || $0.time.contains(requirement) || $0.priceLevel == requirement})

            restaurantCollectionView.reloadData()
        }

    }

}

I can see you use a if statement in the delegate method to check whether the collection view is filterCollectionView .我可以看到您在委托方法中使用if statement来检查集合视图是否为filterCollectionView In that case with this code your filtering method would naturally not get called when the user selects a cell from the restaurantCollectionView because the if statement would return false.在这种情况下,使用此代码,当用户从restaurantCollectionView选择单元格时,您的过滤方法自然不会被调用,因为if statement将返回 false。

With that being said, the collectionView:didSelectItemAtIndexPath: delegate method should get called on both collection views.话虽如此, collectionView:didSelectItemAtIndexPath:委托方法应该在两个集合视图上都被调用。 Your delegates seem to be properly set up, and your view constraints seem correct as well.您的代表似乎已正确设置,并且您的视图约束似乎也正确。 So if it doesn't get called, I would go ahead and start by checking whether you have any targets or gesture recognizers that would overlap with the cell's content view, and could possibly absorb the touches.因此,如果它没有被调用,我会提前 go 并首先检查您是否有任何目标或手势识别器会与单元格的内容视图重叠,并且可能会吸收触摸。

If you have any touch-related methods I would suggest you to first deactivate it and create a minimal project to make sure everything's working fine, and then capture the view hierarchy via the View Debugging tool in Xcode, it will pause your app and allow you to see your UI in 3D.如果您有任何与触摸相关的方法,我建议您首先停用它并创建一个最小项目以确保一切正常,然后通过 Xcode 中的View Debugging工具捕获视图层次结构,它会暂停您的应用程序并允许您在 3D 中查看您的 UI。 From there you can easily see what is wrong.从那里你可以很容易地看到哪里出了问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何有一个视图 controller 有两个集合视图,但只有一个有页眉/页脚视图? - How to have a view controller with two collection views, but only one has header/footer views? 一个视图控制器上的3个集合视图 - 3 Collection Views on One View Controller 一个视图控制器中具有不同重用单元格的两个集合视图 - Two Collection Views with Different Reuse Cells in One View Controller 在集合视图控制器中快速移动两个视图 - Swift a two views within a collection view controller 如何在一个视图中制作两个集合视图? - How to make two collection views in one view? 试图在一个视图控制器中获得两个UICollection视图。 只有一个出现 - Trying to get two UICollection Views in one view controller. only one showing up 如何使两个集合视图出现在同一个视图控制器上? - How to make two collection views appear on the same view controller? 如何在一个视图控制器中合并多个集合视图? - How to incorporate multiple collection views in one view controller? 如何在一个View Controller中拥有多个Collection View? - How can I have multiple Collection Views in one View Controller? 快速加载两个集合视图和一个表视图的coredata - Loading coredata for two collection views and one table view in swift
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM