any View 是 Swift 5.6+ 中引入的一种新的协议类型语法(existential type),它表示“任意实现了 View 协议的值”。
在 SwiftUI 中,所有 UI 元素(Text、VStack、Image 等)都是遵循 View 协议的类型。
例如:
struct ContentView: View {
var body: some View {
Text("Hello")
}
}
这里的 some View 表示「某个具体类型的视图」,编译器知道它是 Text。
any View
anyVie表示:
1、如果有一个值,符合View协议;
2、但不知道它的具体类型;
3、它是动态的(运行时类型不确定);
4、属于「existential type」(存在类型)。
例如:
func printViewInfo(view: any View) {
print("这是一个视图,但我不知道它是什么类型")
}
可以把任何符合View协议的值传给这个函数:
printViewInfo(view: Text("Hello"))
printViewInfo(view: Image(systemName: "star"))
使用场景
1、传递一个View视图的闭包:
class ToolbarWindow: NSWindow {
init(rectOrigin rect: CGPoint,rectSize size: CGSize, ViewBuilder: () -> any View) { // 传递闭包
let swiftUIView = ViewBuilder()
let hostingControllerView = NSHostingController(rootView: AnyView(swiftUIView))
}
}
使用限制
不能把any View用在SwiftUI的视图层,比如:
struct ContentView: View {
let view: any View = Text("Hello")
var body: some View {
VStack {
View // Type 'any View' cannot conform to 'View'
}
.padding()
}
}
因为SwiftUI构建视图树时,需要知道每个节点的具体类型,以便优化渲染性能,而any View隐藏了具体的类型,类型范围太广,不符合视图树的要求。
总结
anyView表示某个遵循View的值,主要用于参数约束:
func display(_ view: any View) {
// view 是某种 View,但类型未知
}
表示某个遵循View协议的值,但不确定具体类型。
属于泛型约束,性能低。
只有运行时决定类型,属于存在类型(existential type)。
不能应用于SwiftUI视图层。
如果要在SwiftUI中实际渲染视图,必须使用具体的类型,如some View或 AnyView。