[英]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.