I have a UICollectionView
inside the UINavigationItem's title view acting as a menu. I am unable to select items within the collection view. If I place the UICollectionView outside of the navigation item and into my view controller, everything works as intended.
UIViewController
let menuView = HomeMenuView()
override func viewDidLoad() {
navigationItem.titleView = menuView
menuView.delegate = self
}
HomeMenuView (UICollectionView)
class HomeMenuView: UIView, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
var sections = ["Recent", "Following"]
var delegate: HomeMenuDelegate!
var selectedIndex = 0
var collectionView: UICollectionView!
override init(frame: CGRect) {
super.init(frame: frame)
create()
}
func create() {
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = 0
layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
addSubview(collectionView)
collectionView.anchor(top: nil, left: nil, bottom: nil, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: UIScreen.main.bounds.width/2, height: 30)
collectionView.center(x: centerXAnchor, y: centerYAnchor)
collectionView.backgroundColor = .clear
collectionView.isUserInteractionEnabled = true
collectionView.clipsToBounds = true
collectionView.allowsSelection = true
collectionView.delegate = self
collectionView.dataSource = self
collectionView.register(HomeMenuCell.self, forCellWithReuseIdentifier: "cellID")
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return sections.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellID", for: indexPath) as! HomeMenuCell
cell.title = sections[indexPath.row]
cell.isSelected = selectedIndex == indexPath.row
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
guard let currentCell = collectionView.cellForItem(at: IndexPath(row: selectedIndex, section: 0)) as? HomeMenuCell else { return }
guard let newCell = collectionView.cellForItem(at: indexPath) as? HomeMenuCell else { return }
currentCell.isSelected = false
newCell.isSelected = true
selectedIndex = indexPath.row
delegate.didSelectSection(at: indexPath.row)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: (collectionView.frame.width)/CGFloat(sections.count), height: collectionView.frame.height)
}
override func layoutSubviews() {
super.layoutSubviews()
collectionView.layer.cornerRadius = collectionView.bounds.height/2
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Your collection view cells cannot be selected because your collection view is outside the bounds of its super view.
Change the middle part of your create()
func as follows (you didn't include your "constraint helpers" so I used standard constraint syntax):
addSubview(collectionView)
collectionView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
collectionView.topAnchor.constraint(equalTo: topAnchor, constant: 0.0),
collectionView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 0.0),
collectionView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: 0.0),
collectionView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: 0.0),
collectionView.widthAnchor.constraint(equalToConstant: UIScreen.main.bounds.width * 0.5),
collectionView.heightAnchor.constraint(equalToConstant: 30.0),
])
//collectionView.anchor(top: nil, left: nil, bottom: nil, right: nil, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: UIScreen.main.bounds.width/2, height: 30)
//collectionView.center(x: centerXAnchor, y: centerYAnchor)
collectionView.backgroundColor = .clear