Hello!
I am trying to create a custom view that basically acts like a Button in SwiftUI. There are two specific initializers of Button that allow you to pass in a label and an action, as well as an action and a custom label, which can be an arbitrary view:
Initializer One:
Button("Button") {
// action
}
Initializer Two:
Button {
// action
} label: {
// label (any view using @ViewBuilder)
}
I want to create a custom view that has two initializers in a similar way. I have laid out a structure as a general example of my goal:
struct GenericView<Content: View>: View {
var label: String
var content: Content?
var body: some View {
content // need help handling based on initializers
}
init(label: String) {
self.label = label
self.content = nil
}
init(label: String, @ViewBuilder content: () -> Content) {
self.label = label
self.content = content()
}
}
Each instance will always have a label. The content property content is of type Content, which is a generic type that conforms to View. I made it optional because you mostly would not need to pass in a custom view. In that case, it would be nil. Otherwise, you can use the second initializer and pass in any view you want with @ViewBuilder.
I have a couple of questions about this.
If I were to call the second initializer:
GenericView(label: "Label") {
// pass in custom view (any view using @ViewBuilder)
}
I don't think it would be a problem. However, it would be an issue if I were to call the first initializer:
GenericView(label: "Label") // ERROR: Generic parameter 'Content' could not be inferred (Explicitly specify the generic arguments to fix this issue)
What does this mean? I thought about moving the generic constraint to the second initializer but I need to define the content property of type Content, so that wouldn't work. I don't want to specify a generic argument like this:
GenericView<Rectangle>(label: "Label")
In addition, I wrote, "need help handling based on initializers" in a comment above. How can I go about deciding on what to show based on the initializer called? I put content in GenericView's body, but I cannot show that if you use the first initializer. It looks like nothing shows on a view if it is nil?
In general, I just need guidance on how to create a struct that acts very closely to a Button in SwiftUI, like I mentioned above. There needs to be an initialzer that will take a couple of properties, and another initializer that will take those properties in addition to an arbitrary view using @ViewBuilder.
To be clear, I am not working on making something that behaves like a button, I just want the behavior of the initializers of Button. I am working on a custom view and the above struct is just for example purposes, my implementation of my actual project is much more involved.
How can I go about this in the best way? Thanks for the help! :)