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
相关产品推荐
相关产品推荐

