Прямоугольник в ZStack изменяет анимацию SwiftUI - PullRequest
1 голос
/ 22 апреля 2020

Я пытаюсь перейти между двумя состояниями с помощью SwiftUI.

Я сократил это до простого примера

struct Test2View: View {

    @State var isLoading: Bool = true

    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 10)
                .fill(Color. secondary)
                .shadow(radius: 4, x: 2, y: 5)
                .frame(width: 300, height: 150, alignment: .center)

            if isLoading {
                Text("Loading")
                .transition(.moveAndFade())
            } else {
                Text("Content")
                .transition(.moveAndFade())
            }
        }.onTapGesture {
            withAnimation {
                self.isLoading.toggle()
            }
        }
    }

}
extension AnyTransition {
    static func moveAndFade(delay: TimeInterval = 0) -> AnyTransition {
        let insertion = AnyTransition.offset(x: 0, y: 15)
            .combined(with: .opacity)
        let removal = AnyTransition.offset(x: 20, y: 20)
            .combined(with: .opacity)
        return .asymmetric(insertion: insertion, removal: removal)
    }
}

Это работает так, как я ожидал без RoundedRectangle:

enter image description here

Однако, как только я добавляю RoundRectangle, я теряю анимацию удаления (если я не прерываю анимацию, вы можете увидеть анимацию, которой я был ожидание):

enter image description here

Есть идеи, почему RoundedRectangle мешает анимации? Я даже пытался добавить .transition(.identity) безуспешно.

1 Ответ

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

Я не могу сказать точную причину, почему анимация меняется, но я нашел причину. Это как-то связано с размером рамки.

Ваша версия Test2View тела просмотра:

ZStack {
    RoundedRectangle(cornerRadius: 10)
        .fill(Color.white)
        .shadow(radius: 4, x: 2, y: 5)
        .frame(width: 300, height: 150, alignment: .center)

    if isLoading {
        Text("Loading")
        .transition(.moveAndFade())
    } else {
        Text("Content")
        .transition(.moveAndFade())
    }
}
.border(Color.red)
.onTapGesture {
    withAnimation {
        self.isLoading.toggle()
    }
}

Фиксированная версия:

ZStack {
    if isLoading {
        Text("Loading")
        .transition(.moveAndFade())
    } else {
        Text("Content")
        .transition(.moveAndFade())
    }
}
.background(
    RoundedRectangle(cornerRadius: 10)
        .fill(Color.white)
        .shadow(radius: 4, x: 2, y: 5)
        .frame(width: 300, height: 150, alignment: .center)
)
.border(Color.green)
.onTapGesture {
    withAnimation {
        self.isLoading.toggle()
    }
}

В основном Я использовал .background вместо создания VStack.

Сравнительные изображения:

Broken Fixed

Цвет рамки используется только для обозначения размера кадра. Вы можете удалить это!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...