I want to create an initialiser for a VStack that takes my custom enum as it's spacing element. I have this code:
enum Styles {
enum Spacing: CGFloat {
case one = 4
case two = 8
case three = 16
}
}
extension VStack where Content: View {
init(
alignment: HorizontalAlignment = .center,
spacing: Styles.Spacing? = nil,
content: () -> Content
) {
self.init(
alignment: alignment,
spacing: spacing?.rawValue ?? Styles.Spacing.three.rawValue,
content: content
)
}
}
When I use my custom VStack initialiser within a @ViewBuilder function, it comes back with the error Type '()' cannot conform to 'View'. Here's an example of when that occurs:
@ViewBuilder
private func textBlock(
question: String,
answer: String
) -> some View {
VStack(
alignment: .leading,
spacing: .three
) {
Text(question)
Text(answer)
}
}
How can I fix this?
CodePudding user response:
You need to mark your content param as @ViewBuilder:
@ViewBuilder content: () -> Content
Some considerations:
- Your current implementation of
textBlockdoesn't need to be marked as@ViewBuilder(unless you plan to add more views after theVStack), so you can remove that. - The optional
spacingparameter will not work at all, because any calls toVStack(alignment: <something>)will collide with your signature (since you provide a default value forspacing) and the compiler will have no clue as to which initializer should be used. So you'll have to make this one non-optional.
