Анимация SwiftUI: некоторые неявные анимации перехода не работают на iOS 13? - PullRequest
2 голосов
/ 31 марта 2020

Протестировано на Xcode 11.3.1 и 11.4:

При прикреплении неявных анимаций к переходу некоторые типы переходов выглядят неработающими. В частности, любые связанные с позицией переходы не применяют данную неявную анимацию. .slide, .move, .offset сломаны. .opacity и .scale кажутся нормальными. (См. Вложение)

Кажется, что во всех случаях явная анимация работает нормально.

Даже при использовании пользовательских составных переходов субпереходы, связанные с положением, не реагируют на неявную анимацию.

Это ошибка или ожидаемое поведение?

Похоже, это было бы проблемой, если вы хотите запустить несколько различных кривых анимации для определенных c элементов пользовательского интерфейса на основе неявного изменение свойства.

enter image description here


struct MyExample: View {

    @State private var isShowing = true

    private let myAnimation = Animation.spring(response: 0.8, dampingFraction: 0.2, blendDuration: 3.0)
    var body: some View {
        VStack(spacing:20) {
            if self.isShowing {
                Text("Opacity").modifier(MyBigFont())
                    .transition(AnyTransition.opacity.animation(myAnimation))

                Text("Scale").modifier(MyBigFont())
                    .transition(AnyTransition.scale.animation(myAnimation))

                Text("Slide").modifier(MyBigFont())
                    .transition(AnyTransition.slide.animation(myAnimation))

                Text("Move").modifier(MyBigFont())
                    .transition(AnyTransition.move(edge: .trailing).animation(myAnimation))

                Text("Offset").modifier(MyBigFont())
                    .transition(AnyTransition.offset(x: 20, y: 0).animation(myAnimation))

                Text("Custom").modifier(MyBigFont())
                    .transition(AnyTransition.myCustomTransition.animation(myAnimation))
            }

            Spacer()

            Button(action: {
                self.isShowing.toggle()
            }) {
                Text("Implicit Toggle")
            }

            Button(action: {
                withAnimation(self.myAnimation) {
                    self.isShowing.toggle()
                }
            }) {
                Text("Explicit Toggle")
            }
        }
    }

}

struct MyBigFont: ViewModifier {
    func body(content: Content) -> some View {
        content
            .lineLimit(1)
            .padding()
            .background(Color.purple)
            .foregroundColor(.white)
            .cornerRadius(8)
            .font(Font.system(size: 21).bold())
    }
}

struct MyCustomTransition: ViewModifier {

    var isEnabled: Bool

    func body(content: Content) -> some View {

        if isEnabled {
            return content
                .offset(x: 20.0, y: 0.0)
                .opacity(0)
        } else {
            return content
                .offset(x: 0.0, y: 0.0)
                .opacity(1)
        }

    }
}

extension AnyTransition {
    static let myCustomTransition = AnyTransition.modifier(
        active: MyCustomTransition(isEnabled: true),
        identity: MyCustomTransition(isEnabled: false))
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        VStack {
            MyExample()
            Spacer()
        }
    }
}

Ответы [ 2 ]

1 голос
/ 07 апреля 2020

Согласно Хавьеру, неявные анимации на переходах больше не работают с Xcode 11.2

Если у кого-то есть более новая информация, пожалуйста, ответьте.

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

https://swiftui-lab.com/advanced-transitions/

0 голосов
/ 03 апреля 2020

Для правильной анимации неявных переходов необходимо создать анимируемый контейнер, включающий эти переходы.

Протестировано с Xcode 11.4 / iOS 13.4.

demo

Вот единственное исправление:

struct MyExample: View {

    @State private var isShowing = true

    private let myAnimation = Animation.spring(response: 0.8, dampingFraction: 0.2, blendDuration: 3.0)
    var body: some View {
        VStack(spacing:20) {
            if self.isShowing {

                ...      // all your code here

            }
        }.animation(myAnimation)    // << fix !!
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...