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
Post
Replies
Boosts
Views
Activity
you're writing to think it doesn't make sense, because var body is doing some sort of meta programming with @ViewBuilder
check out what @ViewBuilder does
Actually, i've been doing this on macOS target. (without mac catalyst) so no simulator.
i don't think it's button style issue either, the example i shared is 100% reproducible, regardless of button style.
it's just that .keyboardShortcut is keep calling "outdated" action, that already been replaced by button.
also, as i wrote on original post, it works perfectly fine if i force rerender of button by changing label to use model.option