Переходы SwiftUI имеют различную реализацию? - PullRequest
0 голосов
/ 31 марта 2020

Я тестировал работу переходов на основе SwiftUI-labs , но обнаружил, что переходы не должны реализовываться одинаково. Основываясь на предыдущей статье:

Обратите внимание, что начиная с XCode 11.2, переходы больше не работают с неявными анимациями

Дело в том, что я нашел что-то странное. Некоторые переходы работают нормально, когда используется неявная анимация ИЛИ, связывая с ней анимацию. Итак, какую анимацию следует использовать? Смотря как. На что? Я не знаю. Я надеюсь, что любой может помочь мне объяснить все это.

В следующем тесте я создал 5 представлений, каждое из которых связано с различным переходом: .opacity, .scale, .move, .slide и combined (.opacity и .move). Вот мои выводы:

ПРИМЕЧАНИЕ: Я ИСПОЛЬЗУЮ XCODE 11.4 И СИМУЛЯТОР!

Переходы с использованием неявной анимации

Только .move и .slide переходы работают нормально (удаление и вставка).

enter image description here

Переходы с использованием явной анимации

Удаление и анимация вставки работает нормально для всех переходов.

enter image description here

Связывание анимации с каждым переходом

Только * Переходы 1050 * и .opacity работают нормально (удаление и вставка).

enter image description here

С моей точки зрения, нет стандартного способа реализации переходов усложняет вещи, более того, при объединении переходов (.combined).

Я что-то упускаю из-за реализации? Вот мой код:

struct TestAnimation: View {
    @State var show : Bool = true
    var colors : [Color] = [.orange, .yellow, .green, .blue, .pink]

    var body: some View {
        VStack(alignment: .leading) {
            Spacer()

            Color.purple
                .frame(height: 100)
                .overlay(
                    Text("Tap Me!").foregroundColor(.white))
                .onTapGesture {
                    // (#1) implicit animation
                    self.show.toggle()

                    // (#2) explicit animation
                    /*withAnimation(Animation.easeInOut(duration: 1)) {
                        self.show.toggle()
                    }*/

                    // (#3) associate an animation with a transition
                    //self.show.toggle()
            }

            HStack {
                if show {
                    Rectangle()
                        .fill(colors[0])
                        .frame(width: 70, height: 100)
                        .overlay(Text("opacity"))
                        .transition(AnyTransition.opacity) // (#1) - doesn't animate, only removes/inserts the view
                        .animation(.easeInOut(duration: 1)) // (#1) 
                        //.transition(AnyTransition.opacity) // (#2) - only animates the removal, not the insertion
                        //.transition(AnyTransition.opacity.animation(.easeInOut(duration: 1))) // (#3) - animates removal and insertion

                    Rectangle()
                        .fill(colors[1])
                        .frame(width: 70, height: 100)
                        .overlay(Text("scale"))
                        .transition(AnyTransition.scale) // (#1) - doesn't animate, only removes/inserts the view
                        .animation(.easeInOut(duration: 1)) // (#1) 
                        //.transition(AnyTransition.scale) // (#2) - only animates the removal, not the insertion
                        //.transition(AnyTransition.scale.animation(.easeInOut(duration: 1))) // (#3) - animates removal and insertion

                    Rectangle()
                        .fill(colors[2])
                        .frame(width: 70, height: 100)
                        .overlay(Text("move"))
                        .transition(AnyTransition.move(edge: .bottom)) // (#1) - animates removal and insertion
                        .animation(.easeInOut(duration: 1)) // (#1) 
                        //.transition(AnyTransition.move(edge: .bottom)) // (#2) - only animates the removal, not the insertion
                        //.transition(AnyTransition.move(edge: .bottom).animation(.easeInOut(duration: 1))) // (#3) - doesn't animate, only removes/inserts the view

                    Rectangle()
                        .fill(colors[3])
                        .frame(width: 70, height: 100)
                        .overlay(Text("slide"))
                        .transition(AnyTransition.slide) // (#1) - animates removal and insertion
                        .animation(.easeInOut(duration: 1)) // (#1) 
                        //.transition(AnyTransition.slide) // (#2) - only animates the removal, not the insertion
                        //.transition(AnyTransition.slide.animation(.easeInOut(duration: 1))) // (#3) - doesn't animate, only removes/inserts the view

                    Rectangle()
                    .fill(colors[4])
                    .frame(width: 70, height: 100)
                    .overlay(Text("op&mv"))
                    .transition(AnyTransition.opacity.combined(with: .move(edge: .bottom))) // (#1) - doesn't animate, only removes/inserts the view
                    .animation(.easeInOut(duration: 1)) // (#1) 
                    //.transition(AnyTransition.opacity.combined(with: .move(edge: .bottom))) // (#2) - only animates removal, not the insertion
                        //.transition(AnyTransition.opacity.combined(with: .move(edge: .bottom)).animation(.easeInOut(duration: 1))) // (#3) - animates removal (it's not smooth), and only animates opacity on insertion
                }
            }
            .frame(height: 100)
            .padding(7)
                .border(Color.gray)
        }
    }

}
...