SwiftUI中如何向另一个视图传递不同类型的子视图?
问题原因
你定义的TestView仅声明了一个泛型参数Content: View,这就要求headerContent和bodyContent两个闭包的返回值必须是同一个类型的View。
你调用时headerContent返回Text类型,bodyContent返回ScrollView<EmptyView>类型,两者类型不匹配,编译器会优先根据第一个传入的header闭包推断Content为Text类型,第二个body闭包返回ScrollView就会抛出类型不匹配的错误。
修复方案
方案1:拆分两个独立泛型参数(推荐)
给header和body分别声明独立的泛型参数,允许两者返回不同的View类型,修改后的TestView代码如下:
struct TestView<HeaderContent: View, BodyContent: View>: View { var headerContent: (() -> HeaderContent)? = nil let bodyContent: () -> BodyContent var body: some View { VStack { headerContent?() bodyContent() } } }
修改后原来的调用代码不需要做任何调整,即可正常编译运行。
方案2:使用AnyView类型擦除(不推荐)
如果不想修改泛型定义,可以在两个闭包返回值外层包装AnyView做类型擦除,强制两个闭包返回类型统一为AnyView,调用代码修改如下:
struct ContentView: View { var body: some View { TestView(headerContent: { AnyView(Text("HeaderContent")) }) { AnyView(ScrollView { }) } } }
该方案会损失SwiftUI的类型检查优势,也会带来额外的性能开销,仅作为临时兼容方案使用。
内容的提问来源于stack exchange,提问作者Axel
相关产品推荐
相关产品推荐

