SwiftUI 使用 visualEffect 视图修饰符
创始人
2025-07-10 01:01:58
0

前言

在 WWDC 23 中,SwiftUI 引入了一个名为 visualEffect 的新视图修饰符。此修饰符允许我们通过访问特定视图的布局信息来附加一组可动画化的视觉效果。下面我们将学习如何在 SwiftUI 中使用新的 visualEffect 视图修饰符。

介绍 visualEffect

让我们从使用 visualEffect 视图修饰符的最简单示例开始。

struct ContentView: View {
    var body: some View {
        Text("Hello World!")
            .visualEffect { initial, geometry in
                initial.offset(geometry.size)
            }
    }
}

正如你在上面的示例中所看到的,我们定义了一个文本视图并附加了 visualEffect 视图修饰符。每当你附加 visualEffect 视图修饰符时,你应该指定效果闭包。这是你应用所有需要的效果的地方。

效果闭包为你提供了两个参数。第一个是附加到视图的效果集合的初始状态。它是 EmptyVisualEffect 类型的实例。我们使用此实例来附加额外的效果。第二个参数是包含视图的所有布局信息的 GeometryProxy 类型的实例,比如 frame、安全区域等。

什么是视觉效果?

视觉效果是可以改变视图的视觉外观但不影响其布局的任何东西。在 SwiftUI 框架的先前版本中,我们有视图修饰符,如缩放、偏移、模糊、对比度、饱和度、不透明度、旋转等。它们全部都是视觉效果,并且现在符合 VisualEffect 协议。你可以在 visualEffect 闭包中使用其中任何一个。

struct ContentView: View {
    
    var body: some View {
        Text("Hello World!")
            .visualEffect { initial, geometry in
                initial
                    .blur(radius: 8)
                    .opacity(0.9)
                    .scaleEffect(.init(width: 2, height: 2))
            }
    }
}

像 frame 和 padding 这样的东西不是视觉效果,你不能在 visualEffect 闭包中使用它们,因为它们修改了视图层次结构的布局。

visualEffect 修饰符视觉效果

visualEffect 视图修饰符是完成旧事物的新方法。我们可以使用旧视图修饰符修改视图的不透明度和偏移。如果你不需要布局信息,你可以继续使用它们。新方法的唯一区别是我们通过从 GeometryProxy 提供的布局信息计算视图的视觉效果的方式来限定视图的视觉效果。

visualEffect 视图修饰符支持可动画化的值。因此,你可以继续使用它根据视图在视图层次结构中的框架和边界来动画化视图的视觉外观。

struct ContentView: View {
    @State private var isScaled = false
    
    var body: some View {
        VStack {
            Button("Scale") {
                isScaled.toggle()
            }
            
            Text("Hello World!")
                .visualEffect { initial, geometry in
                    initial.scaleEffect(
                        CGSize(
                            width: isScaled ? 2 : 1,
                            height: isScaled ? 2 : 1
                        )
                    )
                }
                .animation(.smooth, value: isScaled)
        }
    }
}

完整的代码

import SwiftUI

struct ContentView: View {
    var body: some View {
        Text("Hello World!")
            .visualEffect { initial, geometry in
                initial.offset(geometry.size)
            }
    }
}

struct ContentViewWithEffects: View {
    var body: some View {
        Text("Hello World!")
            .visualEffect { initial, geometry in
                initial
                    .blur(radius: 8)
                    .opacity(0.9)
                    .scaleEffect(.init(width: 2, height: 2))
            }
    }
}

struct ContentViewWithAnimation: View {
    @State private var isScaled = false
    
    var body: some View {
        VStack {
            Button("Scale") {
                isScaled.toggle()
            }
            
            Text("Hello World!")
                .visualEffect { initial, geometry in
                    initial.scaleEffect(
                        CGSize(
                            width: isScaled ? 2 : 1,
                            height: isScaled ? 2 : 1
                        )
                    )
                }
                .animation(.smooth, value: isScaled)
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
        ContentViewWithEffects()
        ContentViewWithAnimation()
    }
}

将上述代码放入 Swift 文件中,然后在 Xcode 中打开并运行,选择合适的模拟器。请注意,由于视觉效果和动画效果,最好在模拟器上查看效果。

总结

本文章介绍了在 SwiftUI 中引入的新视图修饰符 visualEffect。该修饰符允许我们通过访问特定视图的布局信息来附加一组可动画的视觉效果。给出了一些使用 visualEffect 的简单示例,包括如何使用效果闭包以及如何应用一些常见的视觉效果(例如模糊、透明度、缩放)。

此外,还提到了 GeometryProxy 类型的使用,以及 visualEffect 对可动画值的支持,使得可以根据视图的帧和边界来动态调整视觉外观。

最后,指出了 visualEffect 修饰符在向后兼容性方面的注意事项,并建议在不需要布局信息的情况下继续使用传统的视图修饰符。

相关内容

热门资讯

PHP新手之PHP入门 PHP是一种易于学习和使用的服务器端脚本语言。只需要很少的编程知识你就能使用PHP建立一个真正交互的...
网络中立的未来 网络中立性是什... 《牛津词典》中对“网络中立”的解释是“电信运营商应秉持的一种原则,即不考虑来源地提供所有内容和应用的...
各种千兆交换机的数据接口类型详... 千兆交换机有很多值得学习的地方,这里我们主要介绍各种千兆交换机的数据接口类型,作为局域网的主要连接设...
什么是大数据安全 什么是大数据... 在《为什么需要大数据安全分析》一文中,我们已经阐述了一个重要观点,即:安全要素信息呈现出大数据的特征...
如何允许远程连接到MySQL数... [[277004]]【51CTO.com快译】默认情况下,MySQL服务器仅侦听来自localhos...
如何利用交换机和端口设置来管理... 在网络管理中,总是有些人让管理员头疼。下面我们就将介绍一下一个网管员利用交换机以及端口设置等来进行D...
P2P的自白|我不生产内容,我... 现在一提起P2P,人们就会联想到正在被有关部门“围剿”的互联网理财服务。×租宝事件使得劳...
Intel将Moblin社区控... 本周二,非营利机构Linux基金会宣布,他们将担负起Moblin社区的管理工作,而这之前,Mobli...
施耐德电气数据中心整体解决方案... 近日,全球能效管理专家施耐德电气正式启动大型体验活动“能效中国行——2012卡车巡展”,作为该活动的...
Windows恶意软件20年“... 在Windows的早期年代,病毒游走于系统之间,偶尔删除文件(但被删除的文件几乎都是可恢复的),并弹...