matchedGeometryEffect не работает должным образом

#ios #swift #swiftui

#iOS #swift #swiftui

Вопрос:

Используя последний пример из этой статьи о взломе с помощью swift, вы увидите, что текст плохо анимируется, когда isZoomed переключается на false. Я не могу понять, почему…

 struct ContentView: View {
    @Namespace private var animation
    @State private var isZoomed = false

    var frame: CGFloat {
        isZoomed ? 300 : 44
    }

    var body: some View {
        VStack {
            Spacer()

            VStack {
                HStack {
                    RoundedRectangle(cornerRadius: 10)
                        .fill(Color.blue)
                        .frame(width: frame, height: frame)
                        .padding(.top, isZoomed ? 20 : 0)

                    if isZoomed == false {
                        Text("Taylor Swift – 1989")
                            .matchedGeometryEffect(id: "AlbumTitle", in: animation)
                            .font(.headline)
                        Spacer()
                    }
                }

                if isZoomed == true {
                    Text("Taylor Swift – 1989")
                        .matchedGeometryEffect(id: "AlbumTitle", in: animation)
                        .font(.headline)
                        .padding(.bottom, 60)
                    Spacer()
                }
            }
            .onTapGesture {
                withAnimation(.spring()) {
                    self.isZoomed.toggle()
                }
            }
            .padding()
            .frame(maxWidth: .infinity)
            .frame(height: isZoomed ? 400 : 60)
            .background(Color(white: 0.9))
        }
    }
}
 

Ответ №1:

Оберните каждую съемную часть в собственный стек, контейнер будет анимировать удаление представлений должным образом.

Протестировано с Xcode 12.1 / iOS 14.1

 VStack {
    HStack {
        RoundedRectangle(cornerRadius: 10)
            .fill(Color.blue)
            .frame(width: frame, height: frame)
            .padding(.top, isZoomed ? 20 : 0)
        
        HStack {                         // << here !!
            if isZoomed == false {
                Text("Taylor Swift – 1989")
                    .matchedGeometryEffect(id: "AlbumTitle", in: animation)
                    .font(.headline)
                Spacer()
            }}
    }
    VStack {                             // << here !!
        if isZoomed == true {
            Text("Taylor Swift – 1989")
                .matchedGeometryEffect(id: "AlbumTitle", in: animation)
                .font(.headline)
                .padding(.bottom, 60)
            Spacer()
        }
    }
}
 

Комментарии:

1. Существует объяснение этому? Также работает только со вторым VStack.