SwiftUI 使用 visualEffect 視圖修飾符
前言
在 WWDC 23 中,SwiftUI 引入了一個(gè)名為 visualEffect 的新視圖修飾符。此修飾符允許我們通過訪問特定視圖的布局信息來附加一組可動(dòng)畫化的視覺效果。下面我們將學(xué)習(xí)如何在 SwiftUI 中使用新的 visualEffect 視圖修飾符。
介紹 visualEffect
讓我們從使用 visualEffect 視圖修飾符的最簡(jiǎn)單示例開始。
struct ContentView: View {
var body: some View {
Text("Hello World!")
.visualEffect { initial, geometry in
initial.offset(geometry.size)
}
}
}
正如你在上面的示例中所看到的,我們定義了一個(gè)文本視圖并附加了 visualEffect 視圖修飾符。每當(dāng)你附加 visualEffect 視圖修飾符時(shí),你應(yīng)該指定效果閉包。這是你應(yīng)用所有需要的效果的地方。
效果閉包為你提供了兩個(gè)參數(shù)。第一個(gè)是附加到視圖的效果集合的初始狀態(tài)。它是 EmptyVisualEffect 類型的實(shí)例。我們使用此實(shí)例來附加額外的效果。第二個(gè)參數(shù)是包含視圖的所有布局信息的 GeometryProxy 類型的實(shí)例,比如 frame、安全區(qū)域等。
什么是視覺效果?
視覺效果是可以改變視圖的視覺外觀但不影響其布局的任何東西。在 SwiftUI 框架的先前版本中,我們有視圖修飾符,如縮放、偏移、模糊、對(duì)比度、飽和度、不透明度、旋轉(zhuǎn)等。它們?nèi)慷际且曈X效果,并且現(xiàn)在符合 VisualEffect 協(xié)議。你可以在 visualEffect 閉包中使用其中任何一個(gè)。
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 閉包中使用它們,因?yàn)樗鼈冃薷牧艘晥D層次結(jié)構(gòu)的布局。
visualEffect 修飾符視覺效果
visualEffect 視圖修飾符是完成舊事物的新方法。我們可以使用舊視圖修飾符修改視圖的不透明度和偏移。如果你不需要布局信息,你可以繼續(xù)使用它們。新方法的唯一區(qū)別是我們通過從 GeometryProxy 提供的布局信息計(jì)算視圖的視覺效果的方式來限定視圖的視覺效果。
visualEffect 視圖修飾符支持可動(dòng)畫化的值。因此,你可以繼續(xù)使用它根據(jù)視圖在視圖層次結(jié)構(gòu)中的框架和邊界來動(dòng)畫化視圖的視覺外觀。
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 中打開并運(yùn)行,選擇合適的模擬器。請(qǐng)注意,由于視覺效果和動(dòng)畫效果,最好在模擬器上查看效果。
總結(jié)
本文章介紹了在 SwiftUI 中引入的新視圖修飾符 visualEffect。該修飾符允許我們通過訪問特定視圖的布局信息來附加一組可動(dòng)畫的視覺效果。給出了一些使用 visualEffect 的簡(jiǎn)單示例,包括如何使用效果閉包以及如何應(yīng)用一些常見的視覺效果(例如模糊、透明度、縮放)。
此外,還提到了 GeometryProxy 類型的使用,以及 visualEffect 對(duì)可動(dòng)畫值的支持,使得可以根據(jù)視圖的幀和邊界來動(dòng)態(tài)調(diào)整視覺外觀。
最后,指出了 visualEffect 修飾符在向后兼容性方面的注意事項(xiàng),并建議在不需要布局信息的情況下繼續(xù)使用傳統(tǒng)的視圖修飾符。