我可以防止阴影覆盖其他视图吗?

问题描述 投票:0回答:1

我的视图带有很大的阴影模糊的阴影。我希望阴影位于其他视图后面。尝试了一些 zIndexing 的东西,但似乎没有任何效果。这就是正在发生的事情:

bleeding shawdows

简化代码:

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 的背景仍然可见。

Zstack option

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)

            }
        }
    }
}

还有其他可能的解决方案吗?

swiftui shadow
1个回答
0
投票

好的,继续,找到解决方案,将其输入到这里供其他人查找。

我的最终解决方案是创建一个带有阴影背景层的 ZStack。并让按钮将其按下状态传播到 ZStack,以便按下状态也可以由背景层处理。

正常状态:

normal state

按下状态:

pressed state

代码:

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()
}

© www.soinside.com 2019 - 2024. All rights reserved.