krzysztofzablocki / Inject

Hot Reloading for Swift applications!
MIT License
2.35k stars 116 forks source link

Unexpected Behavior with viewDidLoad in Inject Due to Early addAsChild Invocation #104

Open dacaiguoguo opened 4 weeks ago

dacaiguoguo commented 4 weeks ago

Inject is great for efficiently adjusting the UI, but I've encountered some side effects. Specifically, viewDidLoad is called early due to the addAsChild invocation, which leads to some properties set after initialization not being effective in viewDidLoad. This behavior can cause issues with certain setup configurations and property initializations that rely on the typical lifecycle sequence.

krzysztofzablocki commented 4 weeks ago

Can you test if it works well for you if you delay the addAsChild call to host viewDidLoad callback? if you don't see issues with that we could change it in upstream

dacaiguoguo commented 4 weeks ago

view.addSubview(instance.view) triggers viewDidLoad even though the view controller has not yet been pushed.

Code example:

let demoVCHost = Inject.ViewControllerHost(DemoViewController(conversation: selectedConversation))
// demoVCHost.someValue = ... // someValue is used in viewDidLoad method
navigationController?.pushViewController(demoVCHost, animated: true)

In this setup, calling view.addSubview(instance.view) on demoVCHost leads to viewDidLoad being triggered immediately, although demoVCHost has not yet been pushed to the navigation stack. This behavior is causing issues since certain properties (like someValue) need to be set before viewDidLoad is called.

I'm currently unsure how to modify this to resolve the issue.

krzysztofzablocki commented 3 weeks ago

Couldn't we just do add subview in viewDidLoad of the host?

dacaiguoguo commented 3 weeks ago

I try to place the necessary values, like someValue, in the init method to ensure they are correctly set before being accessed in viewDidLoad.

raulolmedocheca commented 2 days ago

I'm having trouble also in my VIPER project due to this, is there any way to avoid this? Passing the arguments through the init solves part of them, but since I need to give the references afterwards, I might find myself with missing references depending on the timing

raulolmedocheca commented 1 day ago

I ended up removing the addAsChild call and moved it to the viewDidLoad of the host. Seems to be working well on my one use case, but I'd like to test it a little bit before submitting a PR. Any suggestions? @krzysztofzablocki

I noticed that the tab bar icons and texts broke with this change, I ended up moving back part of the add child implementation: https://github.com/krzysztofzablocki/Inject/compare/main...raulolmedocheca:Inject:main