问题
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