'SwiftUI, multiple shapes with unified shadow?
Is there a way in SwiftUI to union two shapes so that they cast a unified shadow. I have tried various combinations and modifiers but don't seem to be able to achieve the look I am after. Any insight would be much appreciated.
struct CardView: View {
var body: some View {
Group {
RoundedRectangle(cornerRadius: 20)
.fill(Color.orange)
.frame(width: 200, height: 250)
.zIndex(0)
Circle()
.trim(from: 0.5, to: 1)
.fill(Color.orange)
.frame(width: 100, height: 100)
.offset(y: -125)
.zIndex(1)
}.shadow(color: Color.black, radius: 10, x: 0, y: 0)
}
}
This is what I get, and what I am after ...
NOTE: zIndex
was just something I tried, i.e. both shapes having the same zIndex
etc. its also a quick way to reorder things without having to move the shapes within the container.
Solution 1:[1]
Here is possible solution. Tested with Xcode 11.4 / iOS 13.4
struct CardView: View {
var body: some View {
VStack(spacing: 0) {
Circle()
.trim(from: 0.5, to: 1)
.fill(Color.orange)
.frame(width: 100, height: 100)
.offset(x: 0, y: 50)
RoundedRectangle(cornerRadius: 20)
.fill(Color.orange)
.frame(width: 200, height: 250)
}
.compositingGroup()
.shadow(color: Color.primary, radius: 10, x: 0, y: 0)
}
}
Solution 2:[2]
I think the correct answer is @Asperi's .compositingGroup
as documented here (https://developer.apple.com/documentation/swiftui/group/3284789-compositinggroup) but I'd like to leave a different working version because there are some use cases where you may not be able or want to use .compositingGroup
.
So let's look at .background
, you can copy and paste the code to see in the simulator:
import SwiftUI
struct AnyShapedView: View {
var body: some View {
ZStack {
RoundedRectangle(cornerRadius: 20)
.fill(Color.orange)
.frame(width: 200, height: 250)
.zIndex(0)
Circle()
.trim(from: 0.5, to: 1)
.fill(Color.orange)
.frame(width: 100, height: 100)
.offset(y: -125)
.zIndex(1)
}
}
}
struct ContentView: View {
var body: some View {
AnyShapedView()
.background(
AnyShapedView()
.shadow(color: Color.black, radius: 10, x: 0, y: 0)
)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
The output:
The version above is not the best practice, but nevertheless, try to understand how shapes and cropping work, as in some use cases it might come useful.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 |