boycgit / swiftui-knowledge

收集和 swiftui 相关的知识点
MIT License
2 stars 0 forks source link

【知识点】理解 @ViewBuilder #7

Open boycgit opened 4 years ago

boycgit commented 4 years ago

ViewBuilder 结构使用了 @_functionBuilder 来修饰。而闭包使用 @ViewBuilder 来修饰,就会修改语法树,转调 ViewBuilder 的 buildBlock 函数。

boycgit commented 4 years ago

参考文档

boycgit commented 4 years ago
  1. 得一提的是,由于 buildBlock 的 overload 版本最多泛型参数是 10 个。所以当超过 10 个的时候可以使用 Group包一下; 如果有循环可以展开,则可以使用 ForEach
boycgit commented 4 years ago

借助 @ViewBuilder 可以自定义类似行为的容器

下面我们使用 @ViewBuilder 自定义一个 NotificationView,它具备类似于 VStackHStack 容器功能

import SwiftUI

struct NotificationView<Content: View>: View {
    let content: Content

    init(@ViewBuilder content: () -> Content) {
        self.content = content()
    }

    var body: some View {
        content
            .padding()
            .background(Color(.tertiarySystemBackground))
            .cornerRadius(16)
            .transition(.move(edge: .top))
            .animation(.spring())
    }
}

比如我们可以这么使用:

import SwiftUI

struct ContentView: View {
    @State private var notificationShown = false

    var body: some View {
        VStack {
            if self.notificationShown {
                NotificationView {
                    Text("notification")
                }
            }

            Spacer()

            Button("toggle") {
                self.notificationShown.toggle()
            }

            Spacer()
        }
    }
}