Swift视图View
Swift视图View

Swift视图View

在 SwiftUI 中,View 是一个协议(protocol),它是所有 UI 组件(如 Text、Image、Button、VStack 等)的共同基础。

View 是 SwiftUI 定义的一个协议,用于描述用户界面的一部分:

protocol View {
    associatedtype Body : View
    @ViewBuilder var body: Self.Body { get }
}

View特点

1、协议而非具体类型

View 不是一个可以直接实例化的类型。它只是一个规范,具体的视图(如 Text、Image、VStack 等)都遵循这个规范。

2、组合性强

SwiftUI 允许多个视图组合成一个视图,比如 VStack 组合多个子视图。这一切都基于 View 协议。

3、body 是递归的

每个 View 都需要定义一个 body 属性,返回另一个 View。这个结构是递归的,直到叶子节点返回一个具体的 SwiftUI 视图(例如 Text)。

举例:

struct MyCustomView: View {
    var body: some View {
        VStack {
            Text("Hello")
            Image(systemName: "star")
        }
    }
}

MyCustomView 遵循了 View 协议。

它的 body 返回的是 some View,即某个遵循 View 协议的具体视图组合(VStack)。

所有这些都基于 SwiftUI 的 View 协议。

View、any View和some View之间的关系

View是一个带有关联类型(associatedtype Body)的协议。Swift 中这类协议不能被直接作为类型使用,也就是:

let v: View  // 编译提示:使用协议“View”作为类型必须写为“any View”;这在未来的 Swift 语言模式中将会出现错误

因为编译器不知道Body的实际类型,不能再运行时或编译器为它分配内存布局或生成代码。

some View:静态多态 + 编译器优化

var body: some View {
    Text("Hello")
}

some View 表示返回某个具体实现了 View 的类型,但不告诉调用者它是什么类型。

 它允许使用静态类型检查和编译器优化(比如 inline、布局优化)。

编译器会在编译期确保 some View 的返回始终是一个确定且一致的类型(比如全是 Text 或全是 VStack<…>),否则报错。

例如:

func makeView(_ condition: Bool) -> some View {
    if condition {
        Text("A")
    } else {
        Text("B")   // 仍然是 Text,编译器允许
    }
}

any View的目的:动态多态 + 弱化性能优化

any View(Swift 5.7 引入的新语法)或 AnyView(旧写法)表示不关心实际类型,只关心它遵循了 View 协议。

它会带来运行时开销,因为底层用了类型擦除(type erasure)。

func makeView(_ condition: Bool) -> any View {
    if condition {
        return Text("A")
    } else {
        return Image(systemName: "star")
    }
}

例如:

func makeView(_ condition: Bool) -> any View {
    if condition {
        return Text("A")
    } else {
        return Image(systemName: "star")
    }
}

或者

func makeView(_ condition: Bool) -> AnyView {
    if condition {
        return AnyView(Text("A"))
    } else {
        return AnyView(Image(systemName: "star"))
    }
}

View实现协议约束,但不可以直接作为类型使用。

some View 返回一个具体类型,但隐藏细节,编译器确定类型。

AnyView / any View允许多个不同的 View 类型,运行期类型擦除。

扩展知识

为什么View是协议不是类?

SwiftUI 强调值类型(value type)和声明式编程,不像 UIKit 那样基于继承体系。

协议 + 泛型 + some View 让 SwiftUI 能在编译时确定 UI 结构,提高性能。

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注