Current situation:
I'm trying to create a reusable view in SwiftUI that returns another view passed into it. At the moment I'm using a closure that returns AnyView
, as the parameter.
When I initialize the reusable view I pass on a custom view wrapped inside AnyView()
.
Goal:
Ideally I'd like a way to omit the AnyView()
wrapper and just pass on my CustomViewA
or CustomViewB
as is.
My attempts and issues:
I tried changing the closure parameter to return some View
but I'm getting the following error:
'some' types are only implemented for the declared type of properties and subscripts and the return type of functions
I've seen a few attempts on S.O. to work around that by somehow using a generic parameter but I'm not sure how to implement this in my case or if it's even possible. Also important to note, the closure needs to take a String as its own input parameter.
Example code:
import SwiftUI
struct ReusableView: View {
let outputView: (String) -> AnyView
var body: some View {
outputView("Hello World")
}
}
struct CustomViewA: View {
let label: String
init(_ label: String) {
self.label = label
}
var body: some View {
return Text(label)
}
}
struct CustomViewB: View {
let label: String
init(_ label: String) {
self.label = label
}
var body: some View {
return HStack{
Text(label)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ReusableView() {
AnyView(CustomViewA($0))
}
}
}
You just need to make ReusableView
generic and declare the return type of your closure as the generic type.
struct ReusableView<Output: View>: View {
let outputView: (String) -> Output
var body: some View {
outputView("Hello World")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ReusableView() {
CustomViewA($0)
}
}
}