简体   繁体   中英

Swift 4 Viewcontroller dependency Injection in Class

I'm learning swift and trying to figure out how to add a view controller as a dependency into my Class I'm creating. Ideally I'd like to add it in the init stage so it's 'dependable'

But I can't quite figure it out - so I'm hoping someone can help me along the way. The error I'm getting is: Property 'self.homeController' not initialized at super.init call

Basically I have a Class that creates an overlay with a pop-up on it that has a UICollectionView that is clickable. When the you click the item, the menu animates out and THEN on complete fires the function from the homecontroller.

class SettingLauncher: NSObject, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {


    private let homeController: HomeController

    func showSettings(){

        // window is the full device since the view is smaller due to nav
        if let window = UIApplication.shared.keyWindow {

            blackView.alpha = 0
            blackView.backgroundColor = UIColor(white: 0, alpha: 0.6)
            blackView.frame = window.frame // set RECT to the same size as device
            blackView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleDismiss)))
            window.addSubview(blackView)
            window.addSubview(collectionView)
            let height:CGFloat = CGFloat(settings.count) * cellHeight
            let y = window.frame.height - height
            collectionView.frame = CGRect(x: 0, y: window.frame.height, width: window.frame.width, height: window.frame.height / 2)

            UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: .curveEaseOut, animations: {

                self.blackView.alpha = 1
                self.collectionView.frame = CGRect(x: 0, y: y, width: window.frame.width, height: window.frame.height / 2)

            }, completion: nil)

        }
    }

    @objc func handleDismiss(){
        UIView.animate(withDuration: 0.5,
           animations:{
                self.blackView.alpha = 0

            if let window = UIApplication.shared.keyWindow {
                self.collectionView.frame = CGRect(x: 0, y: window.frame.height, width: window.frame.width, height: window.frame.height / 2)
            }

        }, completion: {_ in
            self.blackView.removeFromSuperview()
            self.homeController.showSettingsController()
        })
    }



    override init(){
        super.init()
        self.homeController = HomeController()
        collectionView.dataSource = self
        collectionView.delegate = self

        collectionView.register(SettingsCell.self, forCellWithReuseIdentifier: cellID)
    }
}

In the homecontroller, The menu button that you click initializes the settingsController and tells it to display:

let settingsLauncher = SettingLauncher()

    @objc func handleMore(){
        settingsLauncher.showSettings()
    }

    func showSettingsController(){
        let dummyController = UIViewController()
        navigationController?.pushViewController(dummyController, animated: true)
    }

The error is telling you that you must have initialised the homeController property before you call super.init() which you don't do.

Change the code to this:

override init(){
    self.homeController = HomeController()
    super.init()
    collectionView.dataSource = self
    collectionView.delegate = self

    collectionView.register(SettingsCell.self, forCellWithReuseIdentifier: cellID)
}

Figured it out with some help from @UpholderOfTruth and @Tj3n. Posting the working code below.

class SettingLauncher: NSObject, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

    let homeController: HomeController

...other UICollectionview functions

    // on Item click insdie UIViewCollection
    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {

        UIView.animate(withDuration: 0.5,
                       animations:{
                        self.blackView.alpha = 0

                        if let window = UIApplication.shared.keyWindow {
                            self.collectionView.frame = CGRect(x: 0, y: window.frame.height, width: window.frame.width, height: window.frame.height / 2)
                        }

        }, completion: {_ in
            let setting = self.settings[indexPath.item]
            self.blackView.removeFromSuperview()

            // Call function from Injected ViewController
            self.homeController.showControllerSetting(setting: setting)
        })

    }

    init(controller: HomeController){
        homeController = controller
        super.init()
        collectionView.dataSource = self
        collectionView.delegate = self
        collectionView.register(SettingsCell.self, forCellWithReuseIdentifier: cellID)
    }
}

Functions in my HomeController initializing the SettingsLauncher class

    lazy var settingsLauncher:SettingLauncher = {
        let launcher = SettingLauncher(controller: self)
        return launcher
    }()

    @objc func handleMore(){
        settingsLauncher.showSettings()
    }

    func showControllerSetting(setting: Setting){
        let dummyController = UIViewController()
        navigationController?.pushViewController(dummyController, animated: true)
    }

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