简体   繁体   中英

Subclass of UICollectionViewCell Subclass that is initialized from a XIB file

class BaseUICollectionViewCell: UICollectionViewCell { // -> This comes from XIB 
    func method() {}
} 

class SubClassUICollectionViewCell: BaseUICollectionViewCell { // -> Overrides some of its super class methods
    override func method() {}
} 

How can I use both of them in my collection view??

before you answer please make sure you create a project and test what I explained here! I need a solution for the current case mentioned here!

class ViewController: UIViewController {
    @IBOutlet var collectionView: UICollectionView!

    public override func viewDidLoad() {
        super.viewDidLoad()
        collectionViewSetup()
    }

    private func collectionViewSetup() {
        collectionView.delegate = self
        collectionView.dataSource = self

        // What is the right thing overe here
        let xib = UINib(nibName: "BaseUICollectionViewCell", bundle: Bundle(for: Self.self))
        collectionView.register(xib, forCellWithReuseIdentifier: "BaseUICollectionViewCell")}
    }
}

// MARK: - UICollectionViewDataSource
extension ViewController: UICollectionViewDataSource, UICollectionViewDelegate {
    public func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    
    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 2
    }
    
    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        // what is the right thing over here
        if indexPath.row %2 == 0 {
            // BaseUICollectionViewCell
        } else {
            // SubClassUICollectionViewCell
        }
        return UICollectionViewCell()
    }
}

You're totally correct that this is a problem. It's as if the xib-based design process is the enemy of the inheritance concept.

You have, I think, three choices:

  • Design the same thing twice in two separate xib files. That way, the class of cell that comes out of the nib is correct from the get-go. You might hate this because it is horribly non-DRY (all the way to "it's a maintenance nightmare"), but as I think you've intuited, that's just what you've let yourself in for, the way the code / class structure is written.

  • Don't use a cell xib. Design the whole thing in code, like the Big Boys do (real programmers don't use Interface Builder); that way, class inheritance works totally in your favor. Or, if you really want to design in Interface Builder, design an ordinary view: in code, rip it out of the nib, plop it into the cell's content view, and hook everything up manually (outlets and actions and such).

  • Don't use class inheritance, use dependency injection instead. Whatever the logic is that would need to differ between your two "classes" would be embodied in a class-inheritance-based helper object that can be injected into the same cell class.

I like the third one best. But the fact that you think you need any "different" code in the cells might itself be a Bad Smell, because cells are views and should not be doing any "thinking". I leave you with that thought.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM