I am trying to create a structure that's holding the dynamic configuration of a popup view. That includes an array of actionButtons
as well as a body
property that will make up the later popup. The body can be seen as the "child views" of the popup, such as text for example. I want to be able to specify child views at will, using the @ViewBuilder
in my initializer.
However, I am getting the following error:
Cannot assign value of type 'some View' to type 'some View' (type of 'PopupConfiguration.body')
public struct PopupConfiguration {
let headline: String
private(set) var body: some View = EmptyView()
let actionButtons: [ActionButtonDefinition]
init(headline: String, @ViewBuilder bodyContent: () -> some View, actionButtons: [ActionButtonDefinition]) {
self.headline = headline
self.body = bodyContent() // Cannot assign value of type 'some View' to type 'some View' (type of 'PopupConfiguration.body')
self.actionButtons = actionButtons
}
}
I am confused now, since the compiler should be able to assign some View
to some View
, right? It's literally the same type, or not?
Can anyone please explain why this generates above shown error?
CodePudding user response:
You need to make use of generics in this case:
public struct PopupConfiguration<Content: View> {
let headline: String
private(set) var body: Content
let actionButtons: [ActionButtonDefinition]
init(headline: String, @ViewBuilder bodyContent: () -> Content, actionButtons: [ActionButtonDefinition]) {
self.headline = headline
self.body = bodyContent()
self.actionButtons = actionButtons
}
}
I recommend you read the opaque types documentation, especially the section "Differences Between Opaque Types and Protocol Types" :)
The main takeaway is that an opaque type refers to one specific type and retains said type informations. In your case, there is no guarantee that var body: some View
and content: () -> some View
will have the same type.