I have a yellow container with a green view inside. I want to move the container while also hiding/showing the inner green view, with an animation. Currently, I'm using .offset
for the movement, and an if
statement for the green view's transition.
The problem is, although the yellow container moves, the green view does not. It simply fades in and out at the destination offset. I want it to also move alongside the yellow container.
This is what I get currently | This is what I want |
---|---|
![]() |
![]() |
Here's my code:
struct ContentView: View {
@State var showingSubview = false
var body: some View {
VStack {
Button("Show Subview") {
withAnimation(.easeInOut(duration: 2)) {
showingSubview.toggle()
}
}
if showingSubview {
Text("Subview")
.padding()
.background(Color.green)
}
}
.padding()
.background(Color.yellow)
.offset(x: showingSubview ? 150 : 0, y: 0)
}
}
How can I make the green view move along with the yellow container, as it fades in and out? Preferably, I'd like to keep using if
or switch
statements for the insertion/removal.
Found a solution a year later, and it's really simple — just add .scaleEffect(1)
!
.clipped() /// prevent the green view from overflowing
.scaleEffect(1) /// the magic modifier!
This is a much cleaner solution that doesn't involve setting custom frames or whatever. Also, it works with if
and switch
statements!
I'm not completely sure why .scaleEffect(1)
works, but it has something to do with how SwiftUI composes views. I think the modifier makes SwiftUI render it as a new group? If anyone knows why, I'd appreciate an answer.
Here's the full code:
struct ContentView: View {
@State var showingSubview = false
var body: some View {
VStack {
Button("Show Subview") {
withAnimation(.easeInOut(duration: 2)) {
showingSubview.toggle()
}
}
if showingSubview {
Text("Subview")
.padding()
.background(Color.green)
}
}
.padding()
.background(Color.yellow)
.clipped() /// 1.
.scaleEffect(1) /// 2.
.offset(x: showingSubview ? 150 : 0, y: 0)
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With