在关于“如何将通用 SwiftUI 视图添加到另一个视图”的问题的答案中,我了解到这可以使用 @ViewBuilder
来完成。
@ViewBuilder
ContentView
视图外部
GenericView<Content: View>
ContentView
GenericView<Content: View>
如果必须在 inside
ContentView
创建 GenericView<Content: View>
,因为它需要一些仅在此处可用的参数,该怎么办?
UserView
UserView
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 视图样式(Swift by Sundell) 有一些很棒的信息。希望你最终能得到类似的结果:
List {
UserView(userId: 987)
UserView(userId: 123)
}
.userViewStyle(.nameOnly)