For people who've been experiencing this issue: There is a really stupid but 100% working fix.
public extension View {
func projectionOffset(x: CGFloat = 0, y: CGFloat = 0) -> some View {
self.projectionOffset(.init(x: x, y: y))
}
func projectionOffset(_ translation: CGPoint) -> some View {
modifier(ProjectionOffsetEffect(translation: translation))
}
}
private struct ProjectionOffsetEffect: GeometryEffect {
var translation: CGPoint
var animatableData: CGPoint.AnimatableData {
get { translation.animatableData }
set { translation = .init(x: newValue.first, y: newValue.second) }
}
public func effectValue(size: CGSize) -> ProjectionTransform {
.init(CGAffineTransform(translationX: translation.x, y: translation.y))
}
}
This will works perfectly with scoped animation.
Text("Hello, world!")
.animation(.default) {
$0
.opacity(animate ? 1 : 0.2)
// .offset(y: animate ? 0 : 100) // <-- DOESN'T WORKS!!!
.projectionOffset(y: animate ? 0 : 100) // <-- WORKS!!!
}
I've spent the last 3 days trying to figure out why every other animatable modifier works fine with scoped animation but not offset().
turns out it can. it's just a bug in the implementation, which I don't understand the how, considering how simple the implementation is, but whatever.
hope this helps! @calin
Topic:
UI Frameworks
SubTopic:
SwiftUI
Tags: