Search code examples
iosswiftuicollectionviewuicollectionviewcell

CollectionViewCells don't appear programmatically - Swift 5


I want to show a collectionView that appears with animation after hitting a button.

The collectionView appears correctly but the collectionViewCells inside don't.

I have set the UICollectionViewDelegate and UICollectionViewDatasource methods correctly but they aren't called (tested with breakPoints).

I'm doing everything programmatically so I also had to register the SettingCell which is a common UICollectionViewCell to the respective cellID.

Also I thought there could be a problem since I was setting the delegate and datasource too late but I don't think so since they are set at the beginning in the init of the mother class.

class SettingsLauncer : NSObject, UICollectionViewDelegate, UICollectionViewDataSource{

var collectionView : UICollectionView = {
    let layout = UICollectionViewLayout()
    let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
    cv.backgroundColor = .white
    return cv
}()


let CelliD = "CelliD"


func handleMoreButton(){
            //creating and adding  View
    if let windowView = UIApplication.shared.keyWindow {

        let width = UIScreen.main.bounds.width
        let height = UIScreen.main.bounds.height
        let heightCollectionView = CGFloat(300)
        let myHeight = height - heightCollectionView

        collectionView.frame = CGRect(x: 0, y: height, width: width, height: 0)

        UIView.animate(withDuration: 0.3, delay: 0, options: .curveEaseOut, animations: {

            windowView.addSubview(self.collectionView)

            self.collectionView.frame = CGRect(x: 0, y: myHeight, width: width, height: heightCollectionView)
        }, completion: nil)
    }
}



func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 3

}

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CelliD, for: indexPath)

    return cell
}



override init(){
    super.init()
    collectionView.register(SettingCell.self, forCellWithReuseIdentifier: CelliD)
    collectionView.delegate = self
    collectionView.delegate = self

}
}

Solution

  • please add these two lines in your init method

        self.collectionView.delegate = self
        self.collectionView.dataSource = yourDataSource
    

    currently you are having

        collectionView.delegate = self
        collectionView.delegate = self
    

    Also make your collectionView lazy ... and assign delgates there

    private lazy var collectionView : UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        layout.scrollDirection = .horizontal
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = .white
        cv.delegate = self
        cv.dataSource = yourDataSource
        cv.translatesAutoresizingMaskIntoConstraints = false
        return cv
    }()