SwiftUI如何在同一画布中同时预览多个视图?
SwiftUI 同时显示多个预览视图的解决方法
问题描述
我在SwiftUI中为CardDetailView创建了四个预览实例,分别对应iPhone 14 Pro Max、iPhone SE(第三代)的横竖屏状态,但Canvas仅能一次显示一个预览视图,希望同时展示所有四个预览效果。
原代码如下:
struct CardDetailView_Previews: PreviewProvider { static var previews: some View { CardDetailView(viewModel: .init(labelLabelViewModel: LabelLabel.ViewModel(topText: "hello", bottomText: .lorem))) .previewDevice("iPhone 14 Pro Max") CardDetailView(viewModel: .init(labelLabelViewModel: LabelLabel.ViewModel(topText: "hello", bottomText: .lorem))) .previewInterfaceOrientation(.landscapeLeft) .previewDevice("iPhone 14 Pro Max") CardDetailView(viewModel: .init(labelLabelViewModel: LabelLabel.ViewModel(topText: "hello", bottomText: .lorem))) .previewInterfaceOrientation(.portrait) .previewDevice("iPhone SE (3rd generation)") CardDetailView(viewModel: .init(labelLabelViewModel: LabelLabel.ViewModel(topText: "hello", bottomText: .lorem))) .previewInterfaceOrientation(.landscapeLeft) .previewDevice("iPhone SE (3rd generation)") } }
解决方法
SwiftUI的PreviewProvider中,如果直接并列多个视图,默认只会渲染最后一个。要同时显示多个预览,需要用容器将它们包裹起来,有两种常用方式:
1. 使用Group(兼容所有Xcode版本)
将所有预览实例放入Group中,SwiftUI会自动渲染组内的每个视图作为独立预览:
struct CardDetailView_Previews: PreviewProvider { static var previews: some View { Group { CardDetailView(viewModel: .init(labelLabelViewModel: LabelLabel.ViewModel(topText: "hello", bottomText: .lorem))) .previewDevice("iPhone 14 Pro Max") .previewDisplayName("iPhone 14 Pro Max - 竖屏") CardDetailView(viewModel: .init(labelLabelViewModel: LabelLabel.ViewModel(topText: "hello", bottomText: .lorem))) .previewInterfaceOrientation(.landscapeLeft) .previewDevice("iPhone 14 Pro Max") .previewDisplayName("iPhone 14 Pro Max - 横屏") CardDetailView(viewModel: .init(labelLabelViewModel: LabelLabel.ViewModel(topText: "hello", bottomText: .lorem))) .previewInterfaceOrientation(.portrait) .previewDevice("iPhone SE (3rd generation)") .previewDisplayName("iPhone SE 3 - 竖屏") CardDetailView(viewModel: .init(labelLabelViewModel: LabelLabel.ViewModel(topText: "hello", bottomText: .lorem))) .previewInterfaceOrientation(.landscapeLeft) .previewDevice("iPhone SE (3rd generation)") .previewDisplayName("iPhone SE 3 - 横屏") } } }
2. 使用PreviewGroup(Xcode 15及以上版本)
Xcode 15引入了PreviewGroup,专门用于管理多个预览,用法和Group一致,但语义更清晰:
struct CardDetailView_Previews: PreviewProvider { static var previews: some View { PreviewGroup { CardDetailView(viewModel: .init(labelLabelViewModel: LabelLabel.ViewModel(topText: "hello", bottomText: .lorem))) .previewDevice("iPhone 14 Pro Max") .previewDisplayName("iPhone 14 Pro Max - 竖屏") CardDetailView(viewModel: .init(labelLabelViewModel: LabelLabel.ViewModel(topText: "hello", bottomText: .lorem))) .previewInterfaceOrientation(.landscapeLeft) .previewDevice("iPhone 14 Pro Max") .previewDisplayName("iPhone 14 Pro Max - 横屏") CardDetailView(viewModel: .init(labelLabelViewModel: LabelLabel.ViewModel(topText: "hello", bottomText: .lorem))) .previewInterfaceOrientation(.portrait) .previewDevice("iPhone SE (3rd generation)") .previewDisplayName("iPhone SE 3 - 竖屏") CardDetailView(viewModel: .init(labelLabelViewModel: LabelLabel.ViewModel(topText: "hello", bottomText: .lorem))) .previewInterfaceOrientation(.landscapeLeft) .previewDevice("iPhone SE (3rd generation)") .previewDisplayName("iPhone SE 3 - 横屏") } } }
额外优化
添加.previewDisplayName()可以给每个预览设置自定义名称,在Canvas中能更直观地区分不同的预览实例。
内容的提问来源于stack exchange,提问作者ScottyBlades
相关产品推荐
相关产品推荐

