I would like to use SwiftUI previews for my view, which is built as a container that contains other Views. For example,
public struct ContainerView<Content: View>: View {
private let title: String
private let mainView: Content
public init(title: String,
@ViewBuilder mainView: () -> Content) {
self.title = title
self.mainView = mainView()
}
public var body: some View {
VStack {
Text(title)
mainView
}
}
}
When I add a #Preview to it, it gives this error: Type of expression is ambiguous without a type annotation. Here's an example of a preview:
#Preview {
let mainView = {
Text("some view")
}
return SummarySectionView(title: "title string",
mainView: mainView)
}
Is is a limitation of Swift previews? Should I use another macro/function to display the preview?
Note: this works as soon as a remove the <Content: View> code, with the mainView attribute and so forth...
EDIT: Based on the comments, I was able to find what was wrong. My less contrived code had a second view parameter, like so:
public struct ContainerView<Content: View>: View {
private let title: String
private let mainView: Content
private let secondaryView: Content
public init(title: String,
@ViewBuilder mainView: () -> Content,
@ViewBuildeer secondaryView: () -> Content) {
self.title = title
self.mainView = mainView()
self.secondaryView = secondaryView()
}
public var body: some View {
VStack {
Text(title)
mainView
secondaryView
}
}
}
Which is fine, except if my 2 views are different, like so:
#Preview {
let mainView = {
Text("some view")
}
let secondaryView = {
Button(action: {}, label: {
Text("Button example")
})
}
return ContainerView(title: "title string",
mainView: mainView,
secondaryView: secondaryView)
}
Because I thought that mainView and secondaryView were both of type View, it would work, but it does not.
Changing the view declaration to this: public struct ContainerView<MainContent: View, SecondaryView: View>: View and making the relevant changes everywhere else resolves my issue.
viewof typeContentbut where I'd pass in aButtonview instead. Is that why I was seeing the error? BothTextandButtonare of typeView; can't they both respect the same<Content: View>constraint?viewof typeContentbut where I'd pass in aButtonview instead" then. It sounds like you are trying to getContentto beTextandButtonat the same time. That obviously doesn't work -Contentcan only be one type. My guess is that you need a second type parameter, but I can't be sure without seeing your code.