如何使用SwiftUI @ViewBuilder创建需要参数的视图?

问题描述 投票:0回答:1

在关于“如何将通用 SwiftUI 视图添加到另一个视图”的问题的答案中,我了解到这可以使用 @ViewBuilder 来完成。

虽然这对于我的大多数用例都适用,但我现在遇到了一个新问题:

    @ViewBuilder
  • 解决方案基本上创建了
    ContentView
    视图
    外部
    GenericView<Content: View>
  • ContentView
  • 然后传递给显示它的
    GenericView<Content: View>
    
    
但是:

如果必须在 inside

ContentView
创建 GenericView<Content: View>,因为它需要一些仅在此处可用的参数,该怎么办?


示例:

    UserView
  • 是通过提供用户 ID 创建的
  • UserView
  • 的视图模型使用 ID 获取用户名。因此创建
    UserView
    的人只知道 ID,而不知道名称。该名称仅在
    UserView
    内可用
    
  • UserView
  • 在应用程序内的不同位置甚至不同的应用程序中使用。不同的地方需要以不同的布局/样式/等显示用户名。为了不将所有布局硬编码到
    UserView
    中,视图是通用的,并被赋予一个
    Content
    视图类型,用于显示用户名
    
    
  • 代码

protocol NameView: View { init(name: String) } struct NameOnlyView: NameView { private let name: String init(name: String) { self.name = name } var body: some View { Text(name) } } struct NameGreetingView: NameView { private let name: String init(name: String) { self.name = name } var body: some View { Text("Hello \(name)") } } struct UserView<Content: NameView>: View { private let name: String private let nameView: Content init(userId: Int, @ViewBuilder nameViewBuilder: (String) -> Content) { name = LoadUserName(usingId: userId) nameView = nameViewBuilder(name) } var body: some View { nameView } } struct SomeView: View { var body: some View { // What I would like to do UserView(userId: 123, NameOnlyView) UserView(userId: 987, NameGreetingView) // What is required instead UserView(userId: 123) { NameOnlyView("Name which is not known here") } } }

当然,我可以移动逻辑以从给定 ID 加载用户名并使其在 
SomeView

中可用。然而,这只是仅在

UserView
中可用但在
SomeView
中不可用的任何值的示例。特别是在不同的应用程序中使用
UserView
时,我不想实现相同的逻辑来在
UserView
的所有可能的父视图中加载用户名(或其他内容)。

可以使用

@ViewBuilder解决方案解决这个问题吗?


这个问题可以在 SwiftUI 中解决吗?

还是我完全走错了路?

swiftui viewbuilder
1个回答
-1
投票
ButtonStyle

,以及博客文章封装 SwiftUI 视图样式(Swift by Sundell) 有一些很棒的信息。希望你最终能得到类似的结果: List { UserView(userId: 987) UserView(userId: 123) } .userViewStyle(.nameOnly)

© www.soinside.com 2019 - 2024. All rights reserved.