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

XCode 15中#Preview宏无法实现SwiftUI多设备视图预览问题

解决Xcode 15中SwiftUI多设备预览失效的问题

问题原因

你原来的代码在Xcode 14里能正常运行,但Xcode 15的#Preview宏和旧版PreviewProvider的逻辑存在差异——通过View扩展里的ForEach生成多设备配置的方式,Xcode 15的预览系统无法正确识别,只会将其当作单个视图重复渲染,最终导致所有预览都显示同一个设备。

两种可行解决方法

方法一:用多个#Preview宏+切换到「所有预览」

为每个目标设备单独创建#Preview块,之后在画布顶部的预览选择器里切换到「All Previews」,就能并排显示所有设备的预览:

struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
    }
}

#Preview("iPhone SE") {
    ContentView()
        .previewDevice(PreviewDevice(rawValue: DeviceName.iPhoneSE.rawValue))
}

#Preview("iPhone 13 mini") {
    ContentView()
        .previewDevice(PreviewDevice(rawValue: DeviceName.iPhone13Mini.rawValue))
}

enum DeviceName: String, CaseIterable {
    case iPhoneSE = "iPhone SE (3rd generation)"
    case iPhone13Mini = "iPhone 13 mini"
}

操作提示:点击画布顶部的设备选择下拉框,找到并选择「All Previews」,即可看到所有设备的预览并排展示。

方法二:回退到旧版PreviewProvider协议

Xcode 15依然兼容旧版预览方式,直接用PreviewProvider实现多设备预览,效果和Xcode 14完全一致:

struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ForEach(DeviceName.allCases, id: \.rawValue) { device in
            ContentView()
                .previewDevice(PreviewDevice(rawValue: device.rawValue))
                .previewDisplayName(device.rawValue)
        }
    }
}

enum DeviceName: String, CaseIterable {
    case iPhoneSE = "iPhone SE (3rd generation)"
    case iPhone13Mini = "iPhone 13 mini"
}

这种方式无需额外操作,画布会直接并排显示所有设备的预览。

补充说明

如果不想编写重复代码,可以把设备遍历的逻辑封装到PreviewProvider的previews里,或者写成静态方法,避免重复配置ContentView()。

内容的提问来源于stack exchange,提问作者JAHelia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 03:01:10