Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI transition offset

Tags:

swift

swiftui

I have a circle which has an offset. The circle appears with a scale animation when I press a button. The problem is that the animation does not start at the offset position of the circle, it starts at it's original position. How do i get the animation to start at the offset position of the circle.

Circle()
    .frame(width: 64, height: 64)
    .foregroundColor(.red)
    .transition(.scale)
    .offset(x: -69, y: 0)
like image 995
xyyx Avatar asked Sep 12 '25 09:09

xyyx


2 Answers

Use alignment guides:

struct ViewsExercise: View {
    @State var show = true

    var body: some View {
        VStack(alignment: .leading, spacing: 20) {
            Spacer()
            Button("Tap") {
                self.show.toggle()
            }
            .font(.title)

            if show {
                Circle()
                    .frame(width: 64, height: 64)
                    .foregroundColor(.red)
                    .alignmentGuide(.leading, computeValue: { d in
                        64
                    })
                    .transition(AnyTransition.scale.animation(.easeInOut(duration: 1)))
            }
            Spacer()
        }
    }
}

enter image description here

You can learn more about alignment guides here. As @Asperi mentioned, the .offset modifier does not change position of view. The view is still at (0,0), so the transition happens at the origin point. If you want to "physically" offset the view then you should use alignment guides.

Hope this helps.

like image 177
Aнгел Avatar answered Sep 15 '25 02:09

Aнгел


Just add animation to transition, like below (tested with Xcode 11.4)

demo

struct Test: View {
    @State private var show = false
    var body: some View {
        VStack {
            Button("Tap") {
                withAnimation {
                    self.show.toggle()
                }
            }
            if show {
                Circle()
                    .frame(width: 64, height: 64)
                    .foregroundColor(.red)
                    .transition(AnyTransition.scale.animation(.default)) // here !!
                    .offset(x: -69, y: 0)
            }
        }
    }
}
like image 29
Asperi Avatar answered Sep 15 '25 01:09

Asperi