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

如何让SwiftUI预览支持ViewModel的多状态测试?

SwiftUI BookmarksView 多状态预览方案

核心思路

通过给BookmarksViewModel添加支持初始数据注入的构造方法,在预览中分别传入空数据和模拟内容数据,实现两种状态的同时预览。

步骤1:改造ViewModel,支持初始数据注入

让ViewModel的构造器接收可选的初始书签数组,默认是空数组,既不影响正常业务逻辑,又能满足预览需求:

class BookmarksViewModel: ObservableObject {
    @Published var bookmarks: [Bookmark]
    
    init(bookmarks: [Bookmark] = []) {
        self.bookmarks = bookmarks
    }
    
    // 你的其他业务逻辑代码...
}

步骤2:调整BookmarksView,接收外部传入的ViewModel

避免在View内部直接初始化ViewModel,改为通过参数接收,提升灵活性:

struct BookmarksView: View {
    @ObservedObject var viewModel: BookmarksViewModel
    
    var body: some View {
        List(viewModel.bookmarks) { bookmark in
            Text(bookmark.title)
        }
        .overlay {
            if viewModel.bookmarks.isEmpty {
                Text("暂无书签")
            }
        }
    }
}

步骤3:在PreviewProvider中同时展示两种状态

使用Group将两个预览实例分组,配合previewDisplayName给每个状态命名,方便在画布中区分:

struct BookmarksView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            // 空状态预览
            BookmarksView(viewModel: BookmarksViewModel(bookmarks: []))
                .previewDisplayName("Empty State")
            
            // 有内容状态预览
            let sampleBookmarks = [
                Bookmark(id: UUID(), title: "SwiftUI 入门指南"),
                Bookmark(id: UUID(), title: "Combine 响应式编程"),
                Bookmark(id: UUID(), title: "iOS 性能优化技巧")
            ]
            BookmarksView(viewModel: BookmarksViewModel(bookmarks: sampleBookmarks))
                .previewDisplayName("Content State")
        }
    }
}

// 示例Bookmark模型(如果你的项目中已有,可忽略)
struct Bookmark: Identifiable {
    let id: UUID
    let title: String
}

额外提示

  • 如果你的ViewModel依赖其他服务(比如网络请求、本地存储),可以进一步抽象为协议,预览时传入模拟实现,实现更复杂的状态测试。
  • 可以结合PreviewDevice给不同状态指定测试设备,覆盖更多场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:52:13