I'm not sure what you mean. Can you show the code declaring item ?
struct Foo: ProvidesGridDetails {
var gridCustomDetails: DetailGridView {
Text("I'm a Foo")
}
}
struct Bar: : ProvidesGridDetails {
//different implementation
var gridCustomDetails: DetailGridView {
Capsule().fill(.green)
}
}
struct Other {
//note this doesn't conform to ProvidesGridDetails, so we won't call gridCustomDetails
}
In your if let statement which ever execution path the program takes the returned view needs to be of the same type (for example they returned Text("aaa") and Text("bbb"), it would compile fine)
So casting it to AnyView solves the problem, that way both execution path return AnyView and satisfies the opaque type requirement
There's also some other v̵̡̱̩̠͔̮̖̒o̸͙͉̙̳̙̗̱͔̹͎̤̾̔̈́͜o̷̡̧̢̨̻̰͓̖̥̙̭̲͇̫͈͛̓̈̈́̕d̶̘̳͙̠͉̯̣̰̥͍̭̫̯͊̈͜o̴̢̧̡͖͉̬͖̻̼͚͈̓̍́̉̕͝ȍ̴̹̼̖̞͙̫̬͖̋̅̔̋ ̵͇̋͗͝m̵̛̱̬̠͍͖̹̼̩͉͕͖̲̓͂̈́̈́̾͊̌̈̊̌̄͘͝à̷̢̧̛̺͙̪̤͈͊̐̉̏͊͗̓̑̎̎̑͌̀ģ̴̡̛͕͕͖̯͈̪̭͇͇̟̄̉̔̾̌͆̓̀̍̔̋̀i̸̛̯͖͖̐̅̈̀̏̒̈̒̏͊̀c̸̨̧̛̣̫̗̲͇̻̖̱̺̹̬̏̃͊̅͂̒̎̎͜͜͝ related to body:
var body: some View {
if param {
Text("Hello")
} else {
Color.red
}
}
// Error below: Function declares an opaque return type, but has no return statements in its body from which to infer an underlying type
var body2: some View {
if param {
return Text("Hello") // ditto without "return"
} else {
return Color.red
}
}
Yep, @ConfusedVorlon it would make sense to provide a more complete code. Another way to solve this would be to make the view generic, it depends upon what exactly your "item" is.
Some essential things are still missing from this code. GridDisplayable, GridDetails, ByView not shown. OTOH many details there could be removed (fonts / shadows, or irrelevant to this question ZStack, VStack, etc).
To see it how we see it - create a brand new project and copy paste your code into it - it will show all things missing.
This isn't that magic, it just isn't obvious: body inherits the @ViewBuilder attribute from the protocol requirement, meaning it's a builder. Your separate property does not. Simply marking the other property @ViewBuilder will give it the same behavior.
protocol CustomizationPoint {
associatedtype Content: View
var customView: Content { get }
}
struct NoNetworkView: View {
let customization: any CustomizationPoint
public var body: some View {
Text("Hello World")
customization.customView // <-- Type 'any View' cannot conform to 'View'
}
}
We can wrap customization.customView in AnyView(), but this has some performance implications. Do any of the new Swift generics and existential implicit opening stuff allow us to avoid AnyView here?
protocol CustomizationPoint {
associatedtype Content: View
var customView: Content { get }
}
struct NoNetworkView<Content: CustomizationPoint>: View {
let customization: Content
public var body: some View {
Text("Hello World")
customization.customView // <-- Now this compiles
}
}