You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 19:20:47