How to send a closure to a View Controller with its own parameters?

I have 2 View Controllers: VC1 and VC2. What I'm trying to do is show VC2 as pan modal bottom sheet once a button is clicked. VC2 contains two buttons but I want their functionalities to be dynamic.

I want to be able to call VC2 anywhere through my app and pass it a completion handler for the first and the second button with a parameter for the second completion to cater for a special case.

So, VC2 should have the following init:

init(completion:((_ params: Any?) -> Void)?=nil, secondCompletion: ((_ params: Any?) -> Void)?=nil)

So if I was to call VC2 this way:

let hideButton = true
VC2(completion: { hideButton in
   userRepository.updateName("...")
})

Would it be possible to read hideButton in VC2 through the closure and perform whatever handling I want for it?

I do not wish to add it as an additional argument to the init because I am looking for reusability. I want to use VC2 anywhere in my app much like an Alert would function, with two buttons "cancel" or "submit" and each would do different things depending on their completion.

For the sake of simplicity, I did not show the right way to present the VC etc. I just want to pass two completion handlers for the 2 buttons of VC2 where each can be modified any time I'd like.

Thanks for your help!

Paprika


If I'm understanding it correctly, you can do something like this:

class VC1: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Add button/etc...
    }

    @objc func didTapLaunchButton() {
        let vc = VC2 { params in
            // do whatever you need with the passed back params
            print("User clicked cancel")
        } secondCompletion: { params in
            // do whatever you need with the passed back params
            print("User clicked submit: \(params)")
        }
        self.present(vc, animated: true, completion: nil)
    }
}

class VC2: UIViewController {
    
    var onCancel: ((_ params: Any?) -> Void)?
    var onSubmit: ((_ params: Any?) -> Void)?

    init(completion:((_ params: Any?) -> Void)? = nil, secondCompletion: ((_ params: Any?) -> Void)? = nil) {
        self.onCancel = completion
        self.onSubmit = secondCompletion
        super.init(nibName: nil, bundle: nil)
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Add your 2 buttons/etc...
        
    }
    
    @objc func didTapCancel() {
        self.dismiss(animated: true, completion: nil)
        guard let onCancel = onCancel else { return }
        onCancel(nil) // pass back whatever info you need...
    }
    
    @objc func didTapSubmit() {
        self.dismiss(animated: true, completion: nil)
        guard let onSubmit = onSubmit else { return }
        onSubmit("Something") // pass back whatever info you need...
    }
}