SwiftUI视图构建方法应使用何种返回类型?
问题分析与解决方案
你的核心问题在于SwiftUI中**不透明返回类型(some View)和存在类型(any View)**的差异,以及AnyView类型擦除的正确使用方式,下面逐个解释错误原因并给出解决方案:
各错误原因拆解
View作为返回类型:Swift 5.7+要求协议作为类型使用时必须用any关键字标注为存在类型,直接写View会触发语法错误。any View无法遵循View:any View是存在类型,代表任意符合View协议的类型,但SwiftUI的body要求返回some View(确定的具体View类型),存在类型无法直接满足不透明类型的要求,因此报错。some View无法重写:some View是不透明返回类型,父类声明该类型后,子类必须返回与父类完全一致的具体View类型,而你的子类B返回的视图结构与父类A不同,因此无法完成重写。AnyView类型转换失败:你没有将返回的VStack视图用AnyView()显式包裹,VStack是符合View的具体类型,但不是AnyView,必须通过构造方法完成类型转换。
可行解决方案
方案一:用any View作为方法返回类型,在视图中包装为AnyView
保持A和B的方法返回any View,在ContentView的body中用AnyView包裹返回值,满足some View的要求:
struct ContentView: View { var body: some View { let a = A() AnyView(a.getView()) } } class A { func getView() -> any View { VStack { Text("a") } } } class B:A { override func getView() -> any View { VStack { Text("b1") Text("b2") } } }
方案二:方法直接返回AnyView,内部完成类型擦除
修改A和B的方法,直接返回AnyView,并将视图用AnyView()包裹,这样ContentView可以直接使用返回值:
struct ContentView: View { var body: some View { let a = A() a.getView() } } class A { func getView() -> AnyView { AnyView(VStack { Text("a") }) } } class B:A { override func getView() -> AnyView { AnyView(VStack { Text("b1") Text("b2") }) } }
内容的提问来源于stack exchange,提问作者Philippe-André Lorin
相关产品推荐
相关产品推荐

