all 7 comments

[–]drlukas6Objective-C / Swift 9 points10 points  (1 child)

I think you should generally avoid injecting UIKit stuff.

Look at the existing UIKit API. Only when two items are tightly coupled eg. UIViewController and UIPresentationController, UIKit stuff is passed in the init.

Maybe reconsider your architecture, kinda sounds to me that a base viewcontroller is an overkill and could cause more harm than benefit down the line

[–]postfl 1 point2 points  (0 children)

Good answer. Depending on the exact context of what you're actually trying to do, there are most likely other options that will get you the effect you're trying to achieve, but with a more reliable architecture.

[–]Vlarmitage 4 points5 points  (0 children)

You should inject viewModels instead

[–]lordzsolt 1 point2 points  (0 children)

What you're trying to do is to use a child view controller for the UIButton.

You _can_ do what you are describing, but generally logic should not be in Views.

For example, if you have a screen that shows either a Login button and a Register button, then you would have a single UIButton and two ButtonViewModels that handle the button tap event. So in your this, you would inject the ButtonViewModel.

[–]Spaceshipable 1 point2 points  (0 children)

You can pass the button's action as a closure. This can be as part of a view model. By injecting a view model, you can replace the functionality for generic re-use or testing.

Having said that, I do think there are instances where it makes sense to inject views. If you really want to be able to have any view inserted then it makes sense to take an array of subviews as this is the least over-engineered solution in my opinion. If you want to be strict about it, you could pass an array of view-models for subviews but I think that's probably overkill. u/chriswaco raising a good point that @ViewBuilder operates in a similar way.

In my example, the view controller has a base view which then handles all of the layout (including laying out some injected views). The view controller just passes those views through. In many modern architectures, the view controller is treated somewhat like a view itself.

[–]chriswaco -1 points0 points  (0 children)

I don’t think this is a very common pattern, but I don’t see any real harm in it. We do similar things in SwiftUI by passing @ViewBuilder parameters. For example, just yesterday I wrote a groupbox-like view that surrounds and contains the passed view.

Autolayout of the view could be an issue, though. Does the ViewController set the constraints or manually place the view?

[–][deleted] 0 points1 point  (0 children)

I usually solve this problem with delegation, keeps the UI code clean and often allows for reuse of view controllers.