如何在SwiftUI预览视图中将@ObservedObject变量传入带自定义init的视图结构体?
如何在SwiftUI预览视图中将@ObservedObject变量传入带自定义init的视图结构体?
嘿,这个问题我之前踩过坑,折腾了好一会儿才摸透门道,现在给你唠唠怎么解决~
首先咱们得先明确场景:你有个自定义了init方法的SwiftUI视图,视图里还依赖着一个@ObservedObject类型的属性,现在想在预览面板里正常展示这个视图对吧?
第一步:先理清楚你的视图结构
假设你的视图和观察对象是这样的(拿你提到的CacheManager举例子):
class CacheManager: ObservableObject { // 这里是你的缓存逻辑,比如缓存图片的存储、读取方法 var cachedImages: [String: UIImage] = [:] } struct RecipeListView: View { @ObservedObject var cacheManager: CacheManager // 自定义初始化方法,不是系统自动合成的那种 init(cacheManager: CacheManager) { self.cacheManager = cacheManager } var body: some View { // 你的食谱列表UI,比如展示食谱名称和缓存的图片 List { Text("番茄炒蛋") Text("糖醋排骨") } } }
第二步:预览视图传参的正确姿势
其实很简单,直接在预览里创建一个CacheManager的实例,然后传给视图的自定义初始化方法就行!
比如这样写预览代码:
struct RecipeListView_Previews: PreviewProvider { // 提前创建一个供预览用的缓存管理器实例 static let previewCache = CacheManager() static var previews: some View { RecipeListView(cacheManager: previewCache) } }
额外小技巧:如果视图还有其他初始化参数
要是你的视图init除了ObservedObject还需要别的参数(比如食谱数据数组),同样的思路,在预览里提前准备好模拟数据传进去就行:
// 更新后的视图,多了recipes参数 struct RecipeListView: View { @ObservedObject var cacheManager: CacheManager let recipes: [String] init(cacheManager: CacheManager, recipes: [String]) { self.cacheManager = cacheManager self.recipes = recipes } var body: some View { List(recipes, id: \.self) { recipe in Text(recipe) } } } // 对应的预览代码 struct RecipeListView_Previews: PreviewProvider { static let previewCache = CacheManager() static let sampleRecipes = ["番茄炒蛋", "糖醋排骨", "鱼香肉丝"] static var previews: some View { RecipeListView(cacheManager: previewCache, recipes: sampleRecipes) } }
踩坑提醒
别在预览里给那个实例加@ObservedObject修饰,完全没必要!视图内部已经用@ObservedObject处理了响应式逻辑,预览只需要老老实实传个普通实例进去就行。
另外,如果担心多个预览共用一个实例会有状态干扰,也可以直接在预览闭包里创建实例,比如:
static var previews: some View { RecipeListView(cacheManager: CacheManager()) }
这样每次预览刷新都会新建一个干净的实例,避免串状态。
内容来源于stack exchange
相关产品推荐
相关产品推荐

