Hey everyone,
I ran into an interesting quirk while working on a SwiftUI project involving the #Preview
macro. I tried using it to test my views under different conditions, much like I would with the PreviewProvider
struct. However, I noticed some unexpected behavior. Let me show you the difference between the two approaches with a quick example:
struct Test_Previews: PreviewProvider {
static var previews: some View {
Group {
Text("First Preview")
.previewDisplayName("1")
Text("Second Preview")
.previewDisplayName("2")
}
}
}
This code should generate two previews in the canvas, each with a different name. And it works perfectly!
But when I use #Previews
, things go differently:
#Preview {
Group {
Text("First Preview")
.previewDisplayName("1")
Text("Second Preview")
.previewDisplayName("2")
}
}
Instead of two previews, it only creates one, combining all the views into a single preview.
In trying to find a solution, I explored two avenues:
- Creating my own macro to mimic the struct's behavior.
- Understanding why the
#Preview
macro doesn't behave as expected.
After some digging, here's what I found:
- Crafting a custom macro seems tricky because Xcode is responsible for opening the canvas, and it seems to rely on internal triggers like the
preview
macro or explicit struct instantiation. - The discrepancy with the original macro might stem from the type of closure it accepts. Despite documentation stating it should be a
@ViewBuilder
, the macro's definition specifies a closure of typebody: @escaping @MainActor() -> any View
, without mentioning@ViewBuilder
.
While using multiple #Preview
instances can generate several previews, it gets tricky when testing constructs like ForEach
, where reverting to the struct becomes necessary.
Overall, I don't see a good reason for the original macro to deviate from the struct's behavior.
Am I missing anything here? Let's discuss it in the comments.