iosswiftuicollectionviewcellcollectionviewindexpath

CollectionView cell instance (Outside of delegate) on UIView is not working swift 5


I have a view called HorizontalMenuCollectionView on which I am loading the collection view. I can use it just by hooking it up with any view (from identity inspector).

All are working perfectly. But now I want to set the background color of the first item cell when this view will be loaded at the beginning. But the cell background color is not changing. What am I missing here?

This is the function where I am trying to set the background color of the item cell

func selectinitialCell() {
    let selectedIndexPath = IndexPath(item: 0, section: 0)
    let cell = menuCollectionView.dequeueReusableCell(withReuseIdentifier: "HorizontalMenuCollectionViewCell", for: selectedIndexPath) as! HorizontalMenuCollectionViewCell
    cell.backgroundColor = UIColor.blue.withAlphaComponent(0.05)
    menuCollectionView.reloadData()
}

This is the full HorizontalMenuCollectionView:

import UIKit

protocol HorizontalMenuCollectionViewDelegate {
    func didSelectItemAtIndexPath(title: String)
}

class HorizontalMenuCollectionView: UIView {
    
    var horizontalMenuCollectionViewDelegate : HorizontalMenuCollectionViewDelegate!
    @IBOutlet weak var menuCollectionView: UICollectionView!
    var objectArray = [String?]()
    var isFirstTimeGettingCalled = true
    
    //This initializer will call from code
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.initialization()
    }
    
    //This initializer will call from XIB
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.initialization()
    }
    
    func initialization() {
        let view = Bundle.main.loadNibNamed("HorizontalMenuCollectionView", owner: self, options: nil)![0] as? UIView
        view?.frame = self.bounds
        self.autoresizingMask = [.flexibleHeight, .flexibleWidth]
        self.addSubview(view!)
        registerNib()
        selectinitialCell()
    }
    
    func selectinitialCell() {
        let selectedIndexPath = IndexPath(item: 0, section: 0)
        let cell = menuCollectionView.dequeueReusableCell(withReuseIdentifier: "HorizontalMenuCollectionViewCell", for: selectedIndexPath) as! HorizontalMenuCollectionViewCell
        cell.backgroundColor = UIColor.blue.withAlphaComponent(0.05)
        menuCollectionView.reloadData()
    }
    
    func registerNib() {
        let horizontalMenuCollectionViewCellNib = UINib(nibName: "HorizontalMenuCollectionViewCell", bundle: nil)
        menuCollectionView.register(horizontalMenuCollectionViewCellNib, forCellWithReuseIdentifier: "HorizontalMenuCollectionViewCell")
    }
}

extension HorizontalMenuCollectionView: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return objectArray.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, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        let text = NSAttributedString(string: objectArray[indexPath.row]!)
        return CGSize(width: text.size().width + 80, height: self.bounds.height)
    }
    
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "HorizontalMenuCollectionViewCell", for: indexPath) as! HorizontalMenuCollectionViewCell
        cell.titleLabel.text = objectArray[indexPath.row]!
        
        let backgroundView = UIView()
        backgroundView.backgroundColor = UIColor.blue.withAlphaComponent(0.05)
        cell.selectedBackgroundView = backgroundView
        
        return cell
    }
    
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        menuCollectionView.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
        horizontalMenuCollectionViewDelegate.didSelectItemAtIndexPath(title: objectArray[indexPath.row]!)
    }
}

Ans the view controller where I am accessing it

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var horizontalMenuCollectionView: HorizontalMenuCollectionView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        horizontalMenuCollectionView.horizontalMenuCollectionViewDelegate = self
        horizontalMenuCollectionView.objectArray = ["A", "AA", "AAA", "AAAA", "AAAAA"]
    }
}

extension ViewController: HorizontalMenuCollectionViewDelegate {
    func didSelectItemAtIndexPath(title: String) {
        print("\(title)")
    }
}

A full sample project is here.


Solution

  • Replace your func selectinitialCell() with the below one.

    func selectinitialCell() {
        menuCollectionView.performBatchUpdates({
            self.menuCollectionView.reloadData()
        }) { (finish) in
            if finish{
                let selectedIndexPath = IndexPath(row: 0, section: 0)
                self.menuCollectionView.selectItem(at: selectedIndexPath, animated: false, scrollPosition: .left)
            }
        }
    }