`ZStack() {
            Circle()
                .stroke(Color.yellow, lineWidth: 3)
                .scaleEffect(animationAmount)
                .opacity(Double(2 - animationAmount))
                .animation(.easeInOut(duration: 2).repeatForever(autoreverses: false), value: animationAmount)
                .background(.blue)
            
            Image(poke.imageUrl)
                .resizable()
                .aspectRatio(contentMode: .fit)
                .padding()
                .clipShape(Circle())
                .scaleEffect(isAnimating ? 1.2 : 1.0) 
                .rotationEffect(.degrees(isAnimating ? 10 : 0))
                .shadow(radius: 8)
                .background(Circle().fill(Color.green))
        }`

I wrote the same code as above When previewed in that view, the circle on the image works normally as I want However, when you come to View with Image and Circle via NavigationLink from the previous View, the location where the animation of Circle() operates does not match the image

I want to use ZStack to put the image and circle in the same position and the animation of the circle works according to the image position.

.animation(.easeInOut(duration: 2).repeatForever(autoreverses: false), value: animationAmount)

The problem is, if you take this cord out, the stroke in the circle is in the desired position

But when I wrote this code, I found that the location of the stroke was at the top of the view

As explained by the code, I want to match the location where the stroke animation of the image and circle works

Is there anyone who can help me

This is translated, if you find it hard to understand please leave a comment thank you

1

There are 1 best solutions below

0
Benzy Neez On

Instead of using a ZStack, try showing the yellow circle as an overlay over the Image. This way, the size and position of the circle will always correspond to the size and position of the image.

  • If the .scaleEffect is applied after the green background and the overlay, these will be scaled too.

  • The blue background can be applied using another .background modifier to the Image. To fill all of the screen background, set a frame with maxWidth: .infinity, maxHeight: .infinity.

  • When you update the flag isAnimating, you can either do it withAnimation, or you can add an .animation modifier to the Image.

NavigationStack {
    NavigationLink("Show image") {
        Image(poke.imageUrl)
            .resizable()
            .aspectRatio(contentMode: .fit)
            .padding()
            .clipShape(Circle())
            .background(Circle().fill(Color.green))
            .overlay {
                Circle()
                    .stroke(Color.yellow, lineWidth: 3)
                    // .scaleEffect(animationAmount)
                    .opacity(Double(2 - animationAmount))
                    .animation(.easeInOut(duration: 2).repeatForever(autoreverses: false), value: animationAmount)
            }
            .scaleEffect(isAnimating ? 1.2 : 1.0) // 이미지 크기 조절
            .rotationEffect(.degrees(isAnimating ? 10 : 0)) // 이미지 회전
            .shadow(radius: 8)
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .background(.blue)
            .animation(.easeInOut(duration: 2).repeatForever(autoreverses: false), value: isAnimating)
            .onAppear {
                isAnimating = true
                animationAmount = 2
            }
            .onDisappear {
                isAnimating = false
                animationAmount = 1
            }
    }
}

Animation