esteemedparomomycin
esteemedparomomycin

Reputation: 183

Why UICollectionView is not responding at all?

I'm setting up a UICollectionView inside a ViewController. However, it won't respond to any user interaction, didSelectItemAt function is not getting called and I am unable to scroll it.

I have set the DataSource and Delegate properly inside the viewDidLoad(). Here is my code:

class WelcomeController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

let padding: CGFloat = 30
var sources = [Source]()
let sourceCellId = "sourceCellId"

func fetchSources() {
    ApiSourceService.sharedInstance.fetchSources() { (root: Sources) in
        self.sources = root.source
        self.sourceCollectionView.reloadData()
    }
}

let backgroundImage: UIImageView = {
   let iv = UIImageView()
    iv.image = UIImage(named: "background")
    iv.contentMode = .scaleAspectFill
    iv.translatesAutoresizingMaskIntoConstraints = false
    iv.clipsToBounds = false
    return iv
}()

let overlayView: UIView = {
   let view = UIView()
    view.translatesAutoresizingMaskIntoConstraints = false
    view.backgroundColor = .white
    return view
}()

let logo: UIImageView = {
    let iv = UIImageView()
    iv.image = UIImage(named: "mylogo")
    iv.translatesAutoresizingMaskIntoConstraints = false
    iv.clipsToBounds = false
    return iv
}()

let defaultButton: UIButton = {
    let ub = UIButton()
    ub.translatesAutoresizingMaskIntoConstraints = false
    ub.setTitle("Inloggen met E-mail", for: .normal)
    ub.setImage(UIImage(named: "envelope"), for: .normal)
    ub.imageEdgeInsets = UIEdgeInsetsMake(15, 0, 15, 0)
    ub.imageView?.contentMode = .scaleAspectFit
    ub.contentHorizontalAlignment = .left
    ub.titleLabel?.font = UIFont.init(name: "Raleway-Regular", size: 16)
    ub.backgroundColor = .cuOrange
    return ub
}()

let continueWithoutButton: UIButton = {
    let ub = UIButton()
    ub.translatesAutoresizingMaskIntoConstraints = false

    let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: "Doorgaan zonder in te loggen")
    let textRange = NSMakeRange(0, attributedString.length)
    attributedString.setColor(color: .cuOrange, forText: "Doorgaan")
    ub.setAttributedTitle(attributedString, for: .normal)

    ub.contentHorizontalAlignment = .center
    ub.titleLabel?.font = UIFont.init(name: "Raleway-Regular", size: 16)
    ub.titleLabel?.textColor = .white
    return ub
}()


let sourceCollectionView: UICollectionView = {
   let layout = UICollectionViewFlowLayout()
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.translatesAutoresizingMaskIntoConstraints = false
    cv.backgroundColor = .white
    return cv
}()



let termsButton: UIButton = {
    let ub = UIButton()
    ub.translatesAutoresizingMaskIntoConstraints = false

    let attributedString: NSMutableAttributedString = NSMutableAttributedString(string: "Met het maken van een account \nof bij inloggen, ga ik akkoord \nmet servicevoorwaarden.")
    let textRange = NSMakeRange(0, attributedString.length)
    attributedString.setColor(color: .cuOrange, forText: "servicevoorwaarden")
    ub.setAttributedTitle(attributedString, for: .normal)

    ub.contentHorizontalAlignment = .center
    ub.contentVerticalAlignment = .bottom
    ub.titleLabel?.lineBreakMode = .byWordWrapping
    ub.titleLabel?.font = UIFont.init(name: "Raleway-Regular", size: 14)
    ub.titleLabel?.textColor = .white
    ub.titleLabel?.textAlignment = .center
    return ub
}()

override func viewDidLoad() {
    super.viewDidLoad()

    fetchSources()

    sourceCollectionView.dataSource = self
    sourceCollectionView.delegate = self
    sourceCollectionView.register(SourceCell.self, forCellWithReuseIdentifier: sourceCellId)

    view.addSubview(backgroundImage)
    view.addSubview(overlayView)
    backgroundImage.addSubview(termsButton)
    backgroundImage.addSubview(logo)
    backgroundImage.addSubview(sourceCollectionView)

    backgroundImage.widthAnchor.constraint(lessThanOrEqualToConstant: 375).isActive = true
    backgroundImage.heightAnchor.constraint(lessThanOrEqualToConstant: 667).isActive = true
    backgroundImage.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    backgroundImage.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true



    logo.centerXAnchor.constraint(equalTo: backgroundImage.centerXAnchor).isActive = true
    logo.topAnchor.constraint(equalTo: backgroundImage.topAnchor, constant: padding).isActive = true
    logo.widthAnchor.constraint(equalToConstant: 107).isActive = true
    logo.heightAnchor.constraint(equalToConstant: 100).isActive = true

    sourceCollectionView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    sourceCollectionView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -(padding*1.5)).isActive = true
    sourceCollectionView.topAnchor.constraint(equalTo: logo.bottomAnchor, constant: padding).isActive = true
    sourceCollectionView.bottomAnchor.constraint(equalTo: termsButton.topAnchor, constant: -(padding*2)).isActive = true

    termsButton.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -padding).isActive = true
    termsButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    termsButton.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -(padding*2)).isActive = true
    termsButton.heightAnchor.constraint(equalToConstant: 40).isActive = true

    sourceCollectionView.reloadData()

}

@objc func closeWelcomeController() {

    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    appDelegate.switchViewControllers()

    self.dismiss(animated: true, completion: {

    })

}


func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

    let width = self.sourceCollectionView.frame.width
    let height = CGFloat(50)

    return CGSize(width: width, height: height)

}

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return sources.count
}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {

    print(sources[indexPath.item].feed_name)

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: sourceCellId, for: indexPath) as! SourceCell
    cell.preservesSuperviewLayoutMargins = true
    cell.source = sources[indexPath.item]

    return cell

}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    print("selecting")
}}

Anyone knows what I am doing wrong here?

I hope there isn't just a "dumb" error inside the code why it's not working, but it's been eating my brain for the past few hours.

Upvotes: 0

Views: 114

Answers (2)

seyha
seyha

Reputation: 554

I see you add sourceCollectionView to subview of backgroundImage. Your backgroundImage is UIImageView so UIImageView doesn't have user interaction except you need to enable it. The problem of your code is

backgroundImage.addSubview(sourceCollectionView)

For my suggestion you should create UIView or other views that can interact with user interaction. It will work fine.

Upvotes: 0

Ahmad F
Ahmad F

Reputation: 31645

It seems that it is inappropriate to add sourceCollectionView as a subview in backgroundImage which is UIImageView! Logically, image view doesn't represent a container view (such as UIView UIStackView, UIScrollView) i.e even if the code lets you do that, it still non-sensible; Furthermore, even if adding a subview to an image view is ok (which is not), image views by default are user interaction disabled (userInteractionEnabled is false by default for image views), that's why you are unable to even scroll the collection view, it is a part (subview) of a disabled user interaction component.

In your viewDidLoad(), you are implementing:

backgroundImage.addSubview(termsButton)
backgroundImage.addSubview(logo)
backgroundImage.addSubview(sourceCollectionView)

Don't do this, instead, add them to main view of the view controller:

view.addSubview(termsButton)
view.addSubview(logo)
view.addSubview(sourceCollectionView)

For the purpose of checking if its the reason of the issue, at least do it for the collection view (view.addSubview(sourceCollectionView)).

And for the purpose of organizing the hierarchy of the view (which on is on top of the other), you could use both: bringSubview(toFront:) or sendSubview(toBack:). For instance, after adding the collection view into the view, you might need to:

view.bringSubview(toFront: sourceCollectionView)

to make sure that the collection view is on top of all components.

Upvotes: 1

Related Questions