在Xcode预览视图代码中,提示:
'@StateObject' used inline will not work unless tagged with '@Previewable' (from macro 'Preview')

这个错误来自Xcode 16 / iOS 18 SDK中SwiftUI预览机制的更新。
在旧版本(Xcode 15及以前),可以正常工作。但是从Xcode 16开始,苹果修改了 #Preview 宏的行为,导致在 #Preview 中不再被允许声明 @StateObject。
'@StateObject' used inline will not work unless tagged with '@Previewable'
这个代码的意思为,不能在 #Preview {} 预览视图代码中直接创建@StateObject。
除非把这个结构体或变量标记为 @Previewable(但这个宏仅供系统内部使用,目前不公开)。
解决方案
将 @StateObject 的逻辑放入一个单独的预览容器中:
#Preview {
PreviewWrapper()
}
struct PreviewWrapper: View {
@StateObject private var iapManager = IAPManager.shared
var body: some View {
ContentView()
.environmentObject(iapManager)
.task {
await iapManager.loadProduct()
await iapManager.handleTransactions()
}
}
}
这个写法兼容Xcode 15和Xcode 16,也不会触发”@StateObject used inline”的编译报错。
@Previewable修饰符
如果想要使用苹果新增的@Previewable修饰符,就需要在预览视图前面添加@Previewable。
#Preview {
ContentPreview()
}
@Previewable
struct ContentPreview: View {
@StateObject var iapManager = IAPManager.shared
var body: some View {
ContentView()
.environmentObject(iapManager)
.task {
await iapManager.loadProduct()
await iapManager.handleTransactions()
}
}
}
需要注意的一点,@Previewable仅支持iOS17及以上的Xcode预览设备。
'@Previewable' can only be used in a #Preview body closure (from macro 'Previewable')
'Previewable()' is only available in iOS 17.0 or newer

如果项目的最低部署目标(Depolyment Target)小于iOS 17,就需要进行iOS版本的条件判断。
因此,在iOS 15+的项目里预览SwiftUI视图,不建议使用 @Previewable。