Adding a UIViewController inside a UICollectionView Cell

前端 未结 4 2064
既然无缘
既然无缘 2021-01-04 04:22

How would I go about inserting a UIViewController inside a UICollectionView Cell?

4条回答
  •  一向
    一向 (楼主)
    2021-01-04 05:01

    It's relatively easy to do this now

    Issue 1, with table views, if you only have a small number of cells, you can simply click to make the cells static - and you're done. Unfortunately with collection views, Apple did not add the ability to make them static. So you have to do it the hard way.

    1, Figure out how to dynamically add a container view in to a normal scene:

    This tutorial: https://stackoverflow.com/a/23403979/294884

    perfectly explains how to add container views dynamically (to ordinary scenes).

    Scroll down to "dynamically load ..."

    2, But cells are not view controllers!

    The fact is your cell will have to know about its own boss view controller:

    class CrazyBigCell: UICollectionViewCell {
        weak var boss: ThatClass? = nil
    

    when you make the cells, set that "boss" variable...

    func collectionView(_ collectionView: UICollectionView,
                    cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        
        let cell = collectionView.dequeueReusableCell(
          withReuseIdentifier: "CrazyBigCellID", for: indexPath) as! CrazyBigCell
        
        cell.boss = self
        cell.data = someData[indexPath.row]
        
        return cell
    }
    

    3, So install the container view, but using the boss's VC

    Follow the tutorial above exactly, but: when it comes to adding the child VC, add it to the boss VC.

    class CrazyBigCell: UICollectionViewCell {
        weak var boss: ThatClass? = nil
        @IBOutlet var chatHolder: UIView!
        var chat: Chat? = nil
        ....
    

    and so ... the secret sauce is: normally you would say something like

            self.addChild(chat!)
    

    but instead it is

            boss?.addChild(chat!)
    

    So ...

    private func _installChatBlock() {
        if chat == nil {
            print(">>> installing chat for " + name etc)
            
            chat = _sb("Chat") as? Chat
            boss?.addChild(chat!)
            chatHolder.addSubview(chat!.view)
            chat!.view.bindEdgesToSuperview()
            chat!.didMove(toParent: boss)
        }
        else {
            print(">>> already had a Chat for " + name etc)
        }
        
        chat!.data = data  // or whatever
        chat!.loadOurChat() // or whatever
    }
    

    Where to call _installChatBlock ?

    Very likely, call that where you set the data for this cell

    var data: [String : Any] = [:] { // whatever
        didSet {
            headline.text = data["headline.text"] // etc
            name.text = data["name"] // etc
            _installChatBlock()
        }
    }
    

    Phew.

提交回复
热议问题