如何为SwiftUI视图预览模拟ViewModel以展示不同状态?
实现SwiftUI视图多状态预览的方法
要在预览中展示视图的不同状态(加载、成功、错误等),核心是让ViewModel的状态可手动控制,无需依赖真实网络请求。以下是具体实现方案:
1. 改造ViewModel,开放状态控制入口
给ViewModel添加带初始状态的初始化方法,或公开状态设置接口,方便预览时直接指定状态:
import SwiftUI import Observation @Observable class TestViewModel { enum State { case loading case success case error(String) // 新增错误状态覆盖更多场景 } private(set) var state: State // 新增带初始状态参数的构造方法 init(initialState: State = .loading) { self.state = initialState } func loadData() async { // 真实环境下的网络请求逻辑 try? await Task.sleep(nanoseconds: 1_000_000_000) self.state = .success } // 可选:公开状态设置方法,方便测试/预览快速切换 func setState(_ state: State) { self.state = state } }
2. 修改视图,支持外部注入ViewModel
将视图内部硬初始化的ViewModel改为外部注入,提升灵活性:
struct TestView: View { @State private var viewModel: TestViewModel private let shouldLoadData: Bool // 新增开关,控制是否触发真实数据加载 // 新增带参数的构造方法,指定默认值不影响原有使用 init(viewModel: TestViewModel = TestViewModel(), shouldLoadData: Bool = true) { self._viewModel = State(wrappedValue: viewModel) self.shouldLoadData = shouldLoadData } var body: some View { Group { switch viewModel.state { case .loading: Text("Loading...") case .success: Text("Success!") case .error(let message): Text("Error: \(message)") } }.task { if shouldLoadData { await viewModel.loadData() } } } }
3. 创建多状态预览
现在可以直接在预览中生成对应状态的ViewModel实例,展示不同视图状态:
#Preview("加载状态") { TestView(viewModel: TestViewModel(initialState: .loading), shouldLoadData: false) } #Preview("成功状态") { TestView(viewModel: TestViewModel(initialState: .success), shouldLoadData: false) } #Preview("错误状态") { TestView(viewModel: TestViewModel(initialState: .error("网络连接失败")), shouldLoadData: false) }
核心思路总结
- 依赖注入:让ViewModel从外部传入,避免视图内部硬编码初始化,提升可测试性和预览灵活性。
- 状态可控:通过构造参数或公开方法直接设置ViewModel状态,无需等待异步请求完成。
- 预览隔离:通过开关关闭预览时的真实数据加载,保证预览快速响应且不受网络环境影响。
内容的提问来源于stack exchange,提问作者ADB
相关产品推荐
相关产品推荐

