SwiftUI现在提供了一个新的、内置的修饰符,可以很容易地为任何视图自动生成一个占位符。例如,假设我们正在开发一个阅读文章的应用程序,它包含以下视图:

struct ArticleView: View {
    var iconName: String
    var title: String
    var authorName: String
    var description: String

    var body: some View {
        VStack(alignment: .leading) {
            HStack {
                Image(systemName: iconName)
                    .foregroundColor(.white)
                    .padding()
                    .background(Circle().fill(Color.secondary))
                VStack(alignment: .leading) {
                    Text(title).font(.title)
                    Text("By " + authorName)
                        .font(.subheadline)
                        .foregroundColor(.gray)
                }
            }
            Text(description).padding(.top)
        }
        .padding()
    }
}

要为上面的视图生成一个占位符,我们现在要做的就是对它应用编辑修饰符,指定.placeholder作为编辑原因:

let placeholder = ArticleView(
    iconName: "doc",
    title: "Placeholder",
    authorName: "Placeholder author",
    description: String(repeating: "Placeholder ", count: 5)
)
.redacted(reason: .placeholder)

当这个修改器被应用时,所有在视图中显示的文本将被灰色的矩形所取代,所以我们在上面传递的实际字符串将只被用来确定这些矩形的大小。

值得注意的是,视图中包含的任何图像(比如ArticleView中显示的图标)仍然会像往常一样显示。 但是,我们可以使用新的redactionReasons环境值来调整这一行为——例如,通过实现一个包装器视图来读取该值,然后有条件地对给定视图应用一个modifier闭包,就像这样

struct RedactingView<Input: View, Output: View>: View {
    var content: Input
    var modifier: (Input) -> Output

    @Environment(\.redactionReasons) private var reasons

    var body: some View {
        if reasons.isEmpty {
            content
        } else {
            modifier(content)
        }
    }
}

有了上述两部分,我们现在可以在需要的时候轻松地应用我们自己的自定义编校逻辑,例如,当生成一个占位符时,可以在ArticleView中隐藏图像;

struct ArticleView: View {
    ...

    var body: some View {
        VStack(alignment: .leading) {
            HStack {
                Image(systemName: iconName)
                    .foregroundColor(.white)
                    .whenRedacted { $0.hidden() }
                    .padding()
                    .background(Circle().fill(Color.secondary))
                ...
            }
            Text(description).padding(.top)
        }
        .padding()
    }
}

SwiftUI还提供了一种方法来取消编辑给定的子视图——这将使它像正常情况下一样渲染,即使它的父视图正在被编辑。下面是我们如何使用这个特性来始终显示我们的文章视图的标题,即使是在生成一个占位符的时候:

struct ArticleView: View {
    ...

    var body: some View {
        VStack(alignment: .leading) {
            HStack {
                Image(systemName: iconName)
                    ...
                VStack(alignment: .leading) {
                    Text(title).font(.title).unredacted()
                    ...
                }
            }
            Text(description).padding(.top)
        }
        .padding()
    }
}

新的修订后的修饰符和它的兄弟api都是swift的内置功能中非常受欢迎的补充;当我们想要渲染一个正在加载内容的UI的“骨架”版本时,或者当创建一个小部件的预览实例时,它都是非常有用的。

原文链接