SwiftUI之ViewBuilder

所属分类:ios | 发布于 2023-01-28

ViewBuilder就是一个包含多个视图的闭包。在SwiftUI框架中,所有的容器视图都使用@ViewBuilder来修饰最后一个参数,因为这些被@ViewBuilder修饰的视图容器可以接收多个子视图作为参数。

ViewBuilder的介绍

1、ViewBuilder的描述

A custom parameter attribute that constructs views from closures.

翻译一下:从闭包构造视图的自定义参数属性

2、ViewBuilder的定义

@resultBuilder struct ViewBuilder

ViewBuilder本质上是一个结构体,并且被@resultBuilder注解,也就是说ViewBuilder是一个result builder(结果建造者)类型。

3、ViewBuilder的理解

使用@resultBuilder注解ViewBuilder结构体之后,就可以用@ViewBuilder来修饰闭包,这个闭包可以接收多个指定类型的对象,而这些对象会按照buildBlock函数的实现进行组织

ViewBuilder结构体有11个名为buildBlock的函数,分别接收从0到10个View类型的参数,因此在SwiftUI中一个接收@ViewBuilder类型参数的视图容器最多能接收10个子视图,如果不能满足需求可以通过拆分来增加子视图的个数。

4、官方示例

通常使用ViewBuilder作为生成闭包参数的子视图的参数属性,允许这些闭包提供多个子视图。例如,以下contextMenu函数接受通过视图生成器生成一个或多个视图的闭包。

4.1、看看contextMenu函数的定义

extension View {
    public func contextMenu<MenuItems>(
        @ViewBuilder menuItems: () -> MenuItems
    ) -> some View where MenuItems : View
}

4.2、使用contextMenu的闭包构建视图

myView.contextMenu {
    Text("Cut")
    Text("Copy")
    Text("Paste")
    if isSymbol {
        Text("Jump to Definition")
    }
}

ViewBuilder的实践

1、自定义容器视图展示@ViewBuilder的用法

1.1、定义一个自定义容器视图

/// - 定义一个自定义容器视图
struct CustomViewBuilderContainerView<Content> : View where Content: View {
    private let content: Content
    
    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }
    
    var body: some View {
        VStack {
            content
                .padding()
        }
        .foregroundColor(.red)
        .background(Color.green)
        .font(.title)
    }
}

1.2、使用自定义容器视图

/// - 自定义容器视图的使用
struct TestViewBuilderView: View {
    var body: some View {
        CustomViewBuilderContainerView {
            Text("Hello, Swift!")
            Text("Hello, SwiftUI!")
        }
    }
}

文哥博客(https://wenge365.com)属于文野个人博客,欢迎浏览使用

联系方式:qq:52292959 邮箱:52292959@qq.com

备案号:粤ICP备18108585号 友情链接