我的视图带有很大的阴影模糊的阴影。我希望阴影位于其他视图后面。尝试了一些 zIndexing 的东西,但似乎没有任何效果。这就是正在发生的事情:
简化代码:
import SwiftUI
struct TestBackgroundView: View {
var body: some View {
VStack {
Color.white.frame(height: 80)
.shadow(color: .red, radius: 40)
Color.white.frame(height: 80)
.shadow(color: .red, radius: 40)
}
}
}
#Preview {
TestBackgroundView()
}
在我自己的代码中,视图是按钮,其中按钮有一个背景阴影,它也会根据按下状态而变化。
我尝试在 ZStack 中覆盖 2 个 VStack,其中背景仅位于底部的 vstack 上。但随后我无法使用清晰的颜色来放置阴影,因此我的按钮动画看起来不正确,因为第一个 VStack 的背景仍然可见。
struct TestBackgroundView: View {
var body: some View {
ZStack {
VStack {
Color.white.frame(height: 80)
.shadow(color: .red, radius: 40)
Color.white.frame(height: 80) // Color.clear will not show shadow
.shadow(color: .red, radius: 40)
}
VStack {
Color.white.frame(height: 80)
Color.black.opacity(0.8) // Simulating pressed state
.padding()
.frame(height: 80)
}
}
}
}
还有其他可能的解决方案吗?
好的,继续,找到解决方案,将其输入到这里供其他人查找。
我的最终解决方案是创建一个带有阴影背景层的 ZStack。并让按钮将其按下状态传播到 ZStack,以便按下状态也可以由背景层处理。
正常状态:
按下状态:
代码:
import SwiftUI
struct TestBackgroundView: View {
@State private var pressedButton: Int?
var body: some View {
ZStack {
VStack {
Color.white.frame(height: 80)
.padding(.horizontal, pressedButton == 1 ? 24 : 0)
.animation(.spring(response: 0.2, dampingFraction: 0.6), value: pressedButton == 1)
.shadow(color: .red, radius: 40)
Color.white.frame(height: 80)
.padding(.horizontal, pressedButton == 2 ? 24 : 0)
.animation(.spring(response: 0.2, dampingFraction: 0.6), value: pressedButton == 2)
.shadow(color: .red, radius: 40)
}
VStack {
Button { } label: {
Text("1").frame(height: 80)
.frame(maxWidth: .infinity)
}
.buttonStyle(TestButtonStyle(isPressed: { isPressed in
if isPressed {
pressedButton = 1
} else {
if pressedButton == 1 {
pressedButton = nil
}
}
}))
Button { } label: {
Text("2").frame(height: 80)
.frame(maxWidth: .infinity)
}
.buttonStyle(TestButtonStyle(isPressed: { isPressed in
if isPressed {
pressedButton = 2
} else {
if pressedButton == 2 {
pressedButton = nil
}
}
}))
}
}
}
}
struct TestButtonStyle: ButtonStyle {
let isPressed: (Bool) -> Void
func makeBody(configuration: Configuration) -> some View {
configuration.label
.background(.white)
.padding(.horizontal, configuration.isPressed ? 24: 0)
.animation(.spring(response: 0.2, dampingFraction: 0.6), value: configuration.isPressed)
.onChange(of: configuration.isPressed) {
isPressed($0)
}
}
}
#Preview {
TestBackgroundView()
}