当可见性设置为私有时使SwiftUI预览工作

63lcw9qa  于 2023-03-11  发布在  Swift
关注(0)|答案(2)|浏览(133)

我有一个SwiftUI视图,如下所示,其中关联的视图模型标记为private

struct BookmarksView: View {
    @StateObject private var viewModel = BookmarksViewModel()
    
    var body: some View {
        switch viewModel.viewState {
        case .empty:
            BookmarksEmptyView()
        case .content(let newsLetters):
            ListView(newsLetters: newsLetters)
        }
    }
}

通过下面的预览,我可以只测试empty的情况,而不是content的情况。

struct BookmarksView_Previews: PreviewProvider {
    static var previews: some View {
        BookmarksView()
    }
}

您能否建议一种方法来测试这两种情况,同时保持private对视图模型可见?
谢谢洛伦佐

8zzbczxx

8zzbczxx1#

您可以创建一个init,这样您就可以注入视图模型,但是使用默认值,这样您就不需要正常使用它。

init(viewModel: BookmarksViewModel = BookmarksViewModel() {
   _viewModel = StateObject(wrappedValue: viewModel)
}

现在,您可以在预览代码中创建和注入示例

jecbmhm3

jecbmhm32#

我终于找到了一种方法来实现这一点,但我不知道这是否是最好的一个:

private struct _BookmarksView: View {
    @Binding var viewState: BookmarksViewState
    
    var body: some View {
        switch viewState {
        case .empty:
            BookmarksEmptyView()
        case .content(let newsletters):
            NewslettersListView(newsletters: newsletters)
        }
    }
}

struct BookmarksView: View {
    @StateObject private var viewModel = BookmarksViewModel()
    
    var body: some View {
        _BookmarksView(viewState: $viewModel.viewState)
    }
}

特别地,内部视图_BookmarksView不再依赖于其视图模型,而仅仅依赖于Binding
这意味着现在我可以预览不包括视图模型的内部状态。

struct BookmarksView_Previews: PreviewProvider {
    
    struct EmptyBookmarksView: View {
        @State var viewState: BookmarksViewState = .empty
        var body: some View {
            _BookmarksView(viewState: $viewState)
        }
    }
    
    struct ContentBookmarksView: View {
        @State var viewState: BookmarksViewState = .content(Newsletter.previews)
        var body: some View {
            _BookmarksView(viewState: $viewState)
        }
    }
    
    static var previews: some View {
        EmptyBookmarksView()
            .previewDisplayName("Empty state")
        ContentBookmarksView()
            .previewDisplayName("Content state")
    }
}

相关问题