In each view I have a similar code block. Would it be possible to pass the view as a parameter? I would like to be able to pass HomeViewDemo(), MainView() or AccountView() as a parameter for the function to generate the simulations of that view for each device.
struct HomeViewDemo_Previews: PreviewProvider {
static var previews: some View {
HomeViewDemo()
.previewDevice(PreviewDevice(rawValue: WPDevice.Phone.name.iPnoneSize0))
.previewDisplayName(WPDevice.Phone.description.iPnoneSize0)
HomeViewDemo()
.previewDevice(PreviewDevice(rawValue: WPDevice.Phone.name.iPnoneSize1))
.previewDisplayName(WPDevice.Phone.description.iPnoneSize1)
HomeViewDemo()
.previewDevice(PreviewDevice(rawValue: WPDevice.Phone.name.iPnoneSize2))
.previewDisplayName(WPDevice.Phone.description.iPnoneSize2)
HomeViewDemo()
.previewDevice(PreviewDevice(rawValue: WPDevice.Phone.name.iPnoneSize3))
.previewDisplayName(WPDevice.Phone.description.iPnoneSize3)
HomeViewDemo()
.previewDevice(PreviewDevice(rawValue: WPDevice.Phone.name.iPnoneSize4))
.previewDisplayName(WPDevice.Phone.description.iPnoneSize4)
HomeViewDemo()
.previewDevice(PreviewDevice(rawValue: WPDevice.Phone.name.iPnoneSize5))
.previewDisplayName(WPDevice.Phone.description.iPnoneSize5)
HomeViewDemo()
.previewDevice(PreviewDevice(rawValue: WPDevice.Phone.name.iPnoneSize6))
.previewDisplayName(WPDevice.Phone.description.iPnoneSize6)
HomeViewDemo()
.previewDevice(PreviewDevice(rawValue: WPDevice.Phone.name.iPnoneSize7))
.previewDisplayName(WPDevice.Phone.description.iPnoneSize7)
}
}
I have solved this by defining a config struct:
struct PreviewConfig: Identifiable {
enum Size {
case smallest
case averge
case largest
}
let size: Size
let colorScheme: ColorScheme
let sizeCategory: ContentSizeCategory
let displayName: String
let id = UUID()
var device: PreviewDevice {
switch size {
case .smallest:
return PreviewDevice(rawValue: "iPhone SE (1st generation)")
case .averge:
return PreviewDevice(rawValue: "iPhone 11 Pro")
case .largest:
return PreviewDevice(rawValue: "iPhone 14 Pro Max")
}
}
}
I also have an Array with my most commonly used ones:
extension Array where Element == PreviewConfig {
static let core = [
PreviewConfig(
size: .averge,
colorScheme: .light,
sizeCategory: .large,
displayName: "Average iPhone"),
PreviewConfig(
size: .averge,
colorScheme: .dark,
sizeCategory: .large,
displayName: "Average iPhone - dark mode"),
PreviewConfig(
size: .averge,
colorScheme: .light,
sizeCategory: .extraExtraLarge,
displayName: "Average iPhone - large font"),
PreviewConfig(
size: .smallest,
colorScheme: .light,
sizeCategory: .large,
displayName: "Smallest iPhone"),
PreviewConfig(
size: .largest,
colorScheme: .light,
sizeCategory: .large,
displayName: "Largest iPhone")
]
}
and a helper method to apply them:
extension View {
func applyPreviewConfigs(_ configs: [PreviewConfig]) -> some View {
Group {
ForEach(configs) { config in
previewDevice(config.device)
.preferredColorScheme(config.colorScheme)
.environment(\.sizeCategory, config.sizeCategory)
.previewDisplayName(config.displayName)
}
}
}
}
which allows me to simply have previews like this:
struct HomeViewDemo_Previews: PreviewProvider {
static var previews: some View {
HomeViewDemo()
.applyPreviewConfigs(.core)
}
}