The code:
import SwiftUI
public struct Snackbar<Content>: View where Content: View {
private var content: Content
// Works OK
public init(@ViewBuilder content: () -> Content) {
self.content = content()
}
init(_ text: String) {
self.init {
Text(text) // cannot convert value of type 'Text' to closure result type 'Content'
.font(.subheadline)
.foregroundColor(.white)
.multilineTextAlignment(.leading)
}
}
public var body: some View {
HStack {
VStack(alignment: .leading, spacing: 4) {
content
}
Spacer()
}
.frame(maxWidth: .infinity,
minHeight: 26)
.padding(.fullPadding)
.background(Color.black)
.clipShape(RoundedRectangle(cornerRadius: .defaultCornerRadius))
.shadow(color: Color.black.opacity(0.125), radius: 4, y: 4)
.padding()
}
}
I'm getting this error:
cannot convert value of type 'Text' to closure result type 'Content'
The goal I'm trying to achieve is to have 2 separate initializers, one for the content of type View
and the other is a shortcut for a string, which will place a predefined Text
component with some styling in place of Content
.
Why am I getting this error if Text
is some View
and I think it should compile.
You can specify the type of Content
.
Code:
public struct Snackbar<Content>: View where Content: View {
private var content: Content
// Works OK
public init(@ViewBuilder content: () -> Content) {
self.content = content()
}
init(_ text: String) where Content == ModifiedContent<Text, _EnvironmentKeyWritingModifier<TextAlignment>> {
self.init {
Text(text)
.font(.subheadline)
.foregroundColor(.white)
.multilineTextAlignment(.leading) as! ModifiedContent<Text, _EnvironmentKeyWritingModifier<TextAlignment>>
}
}
/* ... */
}
The only difference here is the where
after the init
and the force-cast to the type inside the init
.
To avoid the specific type, you can abstract this into a separate view:
init(_ text: String) where Content == ModifiedText {
self.init {
ModifiedText(text: text)
}
}
/* ... */
struct ModifiedText: View {
let text: String
var body: some View {
Text(text)
.font(.subheadline)
.foregroundColor(.white)
.multilineTextAlignment(.leading)
}
}