I have a UICollectionView inside of a UIViewController declared as follows:
class CollectionViewController : UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource, UICollectionViewDelegate {
private var tables = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
var collectionView : UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.minimumInteritemSpacing = 0
layout.minimumLineSpacing = 0
collectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
collectionView.delegate = self
collectionView.dataSource = self
collectionView.showsVerticalScrollIndicator = false
collectionView.backgroundColor = UIColor.clear
collectionView.register(TableBookingCell.self, forCellWithReuseIdentifier: "TableBookingCell")
collectionView.isUserInteractionEnabled = true
self.view.isUserInteractionEnabled = true
self.view.addSubview(collectionView)
collectionView.snp.makeConstraints {
make in
make.edges.equalTo(view)
}
}
//MARK: - CollectionViewDelegate
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return tables.count
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: self.view.frame.width, height: 80)
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TableBookingCell", for: indexPath) as! TableBookingCell
cell.isUserInteractionEnabled = true
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
if indexPath.row < self.tables.count {
print("logging click")
}
}
}
I am next embedding this CollectionViewController inside of another UIViewController and adding it's view to sit inside of a UIView nested in a ScrollView as shown below:
class HomeController: UIViewController, UIScrollViewDelegate {
private let scrollView = UIScrollView()
private let contentContainer = UIView()
private let collectionViewController = CollectionViewController()
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
}
override func viewDidLoad() {
super.viewDidLoad()
scrollView.contentInsetAdjustmentBehavior = .never
scrollView.delegate = self
contentContainer.backgroundColor = .clear
view.addSubview(scrollView)
scrollView.addSubview(contentContainer)
self.addChild(collectionViewController)
contentContainer.addSubview(collectionViewController.view)
collectionViewController.didMove(toParent: self)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
self.scrollView.contentSize = CGSize(width: self.scrollView.contentSize.width , height: self.collectionViewController.collectionView.contentSize.height + self.scrollView.contentSize.height)
}
scrollView.snp.makeConstraints {
make in
make.edges.equalTo(view)
}
imageContainer.snp.makeConstraints {
make in
make.top.equalTo(scrollView)
make.left.right.equalTo(view)
make.height.equalTo(imageContainer.snp.width).multipliedBy(0.7)
}
infoContainer.snp.makeConstraints {
make in
make.top.equalTo(imageView.snp.bottom).offset(-70)
make.bottom.equalTo(imageView).offset(-10)
make.left.equalTo(imageView).offset(10)
make.right.equalTo(imageView).offset(-50)
}
imageView.snp.makeConstraints {
make in
make.left.right.equalTo(imageContainer)
//** Note the priorities
make.top.equalTo(view).priority(.high)
//** We add a height constraint too
make.height.greaterThanOrEqualTo(imageContainer.snp.height).priority(.required)
//** And keep the bottom constraint
make.bottom.equalTo(imageContainer.snp.bottom)
}
contentContainer.snp.makeConstraints {
make in
make.top.equalTo(imageContainer.snp.bottom)
make.left.right.equalTo(view)
make.bottom.equalTo(scrollView)
}
collectionViewController.view.snp.makeConstraints {
make in
// make.edges.equalTo(contentContainer).inset(14)
make.left.right.equalTo(view)
make.top.equalTo(contentContainer)
make.bottom.equalTo(view)
}
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
scrollView.scrollIndicatorInsets = view.safeAreaInsets
scrollView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: view.safeAreaInsets.bottom, right: 0)
}
//MARK: - Scroll View Delegate
private var previousStatusBarHidden = false
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if previousStatusBarHidden != shouldHideStatusBar {
UIView.animate(withDuration: 0.2, animations: {
self.setNeedsStatusBarAppearanceUpdate()
})
previousStatusBarHidden = shouldHideStatusBar
}
}
}
however the UICollectionView is not responding to any touchUpInside events.
It seems contentContainer is missing a height constraints. If adding the following code, you will see what I mean
In this case, you cannot see collectionView at all.
Add the height constraint and align the bottom of contentContainer and CollectionViewController can make everything look right.
It's not all the story but specifically answer why the collectionView won't respond to touch event. Hope you got it.