SwiftUI-переходы условных дочерних представлений - PullRequest
2 голосов
/ 14 февраля 2020

Я пытаюсь понять и поэкспериментировать с переходами представления swiftUI и могу немного понять, почему следующее не работает так, как я ожидаю:

struct ContentView: View {
@State private var showOverlay: Bool = false

var body: some View {
    ZStack {
        VStack {
            Button(action: {
                withAnimation(.easeInOut) {
                    self.showOverlay = true
                }
            }) {
                Text("Hello, World!")
            }
        }
        .zIndex(0)
        .animation(nil)
        .blur(radius: showOverlay ? 3 : 0)

        if showOverlay {
            HStack {
                Button(action: {
                    withAnimation(.easeInOut) {
                        self.showOverlay = false
                    }
                }) {
                    Text("Close")
                }
                .frame(width: 80, height: 80)
                .background(Color.red)
                .transition(.move(edge: .top))

                Button(action: {
                    withAnimation(.easeInOut) {
                        self.showOverlay = false
                    }
                }) {
                    Text("Close")
                }
                .frame(width: 80, height: 80)
                .background(Color.red)
                .transition(.move(edge: .bottom))
            }
            .zIndex(1.0)
        }
    }
}

Существует условный HStack из двух кнопок. Когда параметр @State showOverlay изменяется, это делается в блоке withAnimation. Переходы на отдельные кнопки не учитываются.

Если я удаляю HStack и помещаю zIndex (1) на каждую кнопку, происходит переход удаления, но не переход вставки.

Я хочу, чтобы обе кнопки переходили по назначению, когда их группа добавляется в представление.

Вопросы: Почему перенос в HStack приводит к игнорированию внутренних переходов? Почему краевой переход работает только в 1 направлении?

Ответы [ 2 ]

1 голос
/ 14 февраля 2020

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

Примечание: переходы должны быть проверены на симуляторе или реальном устройстве, большинство из них не работают в режиме предварительного просмотра.

Ниже приведена измененная часть кода, которая дает работоспособное поведение. Протестировано с Xcode 11.2 / iOS 13.2

enter image description here

if showOverlay {
    HStack {
        Button(action: {
            withAnimation(.easeInOut) {
                self.showOverlay = false
            }
        }) {
            Text("Close")
        }
        .frame(width: 80, height: 80)
        .background(Color.red)

        Button(action: {
            withAnimation(.easeInOut) {
                self.showOverlay = false
            }
        }) {
            Text("Close")
        }
        .frame(width: 80, height: 80)
        .background(Color.red)
    }
    .transition(.move(edge: .top)) // << only in this place needed
    .zIndex(1.0)
}
0 голосов
/ 18 февраля 2020

Чтобы получить две разные анимации, вы можете подтянуть условный лог c ближе к кнопкам, т. Е. Внутри HStack:

HStack {
  if showOverlay {
    Button(action: {
      withAnimation(.easeInOut) {
        self.showOverlay = false
      }
    }) {
      Text("Close")
    }
    .frame(width: 80, height: 80)
    .background(Color.red)
    .transition(.move(edge: .top))

    Button(action: {
      withAnimation(.easeInOut) {
        self.showOverlay = false
      }
    }) {
      Text("Close")
    }
    .frame(width: 80, height: 80)
    .background(Color.red)
    .transition(.move(edge: .bottom))
  }
}
.zIndex(1.0)

Это оставляет вас пустым HStack когда showOverlay == false, но это не должно быть большой проблемой, по крайней мере, в этом примере.

...