How to apply shadow to interior views in SwiftUI?

大城市里の小女人 提交于 2021-02-17 18:51:34

问题


I have added a shadow around the VStack that holds my two text fields and a submit button. However, the shadow is also being applied to the two text fields inside the VStack.

Is there something I am missing here that is causing this to happen? I tried adding shadow(radius: 0) on the text fields, but it doesn't change anything. If I remove the padding and background from the text fields, then the shadow goes away.

var body: some View {
    VStack() {
        Spacer()

        VStack() {
            TextField($email, placeholder: Text("email"))
                .padding()
                .background(Color(red: 242 / 255, green: 242 / 255, blue: 242 / 255))

            SecureField($password, placeholder: Text("password"))
                .padding()
                .background(Color(red: 242 / 255, green: 242 / 255, blue: 242 / 255))

            Button(action: { self.login() }, label: { Text("Login").foregroundColor(Color.white) })
                .padding()
                .background(Color(red: 0, green: 116 / 255, blue: 217 / 255))
        }
        .padding()
        .background(Color.white)
        .shadow(radius: 10)

        Spacer()
    }
    .padding()
    .background(Color(red: 0, green: 116 / 255, blue: 217 / 255))
    .edgesIgnoringSafeArea(.all)
}

回答1:


You can use clipped() here to fix this

VStack() {
    Text("Text")
        .background(Color.red)
        .padding()
        .padding()

    Text("Text")
        .background(Color.purple)
        .padding()
}
.padding()
.background(Color.white)

.clipped()
.shadow(color: Color.red, radius: 10, x: 0, y: 0)

Output:

Hope it is helpful :)




回答2:


For me it also worked to apply the shadow to the background instead of the Stack, e.g:

VStack {
  // ...
}.background(Rectangle().fill(Color.white).shadow(radius: 8))



回答3:


For the user's who are struggling to have this work for RoundedRectangle, use:

HStack {
 // Your nested views
}
.overlay(
  RoundedRectangle(cornerRadius: 10)
   .stroke(Color.black.opacity(0.2), lineWidth: 1)
)
.background(
   RoundedRectangle(
     cornerRadius: 10
   )
   .foregroundColor(Color.white)
   .shadow(
     color: Color.black,
     radius: 5,
     x: 0,
     y: 0
   )
)

The shadow is applied in the .background, RoundedRectagle element shadow.

While quite verbose, it's easy to read and the same principle can be applied to and from any other shape.




回答4:


There is a dedicated modifier for this - compositingGroup.

From documentation:

/// Wraps this view in a compositing group.
///
/// A compositing group makes compositing effects in this view's ancestor
/// views, such as opacity and the blend mode, take effect before this view
/// is rendered.
/// [...] 
/// This limits the scope of [...] change to the outermost view.
VStack {
    Text("Text")
        .background(Color.red)
        .padding()
        .padding()
    Text("Text")
        .background(Color.purple)
        .padding()
}
.padding()
.background(Color.white)
.compositingGroup()
.shadow(color: Color.red, radius: 10, x: 0, y: 0)



回答5:


You can work around the issue by using a ZStack to put a Rectangle,Capsule,Circle or other shape behind the VStack. Then apply modifiers to the shape instead of the VStack itself.

ZStack() {
    Capsule()
        .frame(width: 50, height: 50)
        .background(Color.white)
        .shadow(radius: 10)

    VStack() {
        //...
    }
}

Seems like a pretty annoying feature to me, there are many times when you would want a shadow on a container without it being applied to all its elements.

If anyone knows a better way please share, thanks!



来源:https://stackoverflow.com/questions/56518868/how-to-apply-shadow-to-interior-views-in-swiftui

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!