Переходы SwiftUI условных дочерних представлений
Я пытаюсь понять и поэкспериментировать с переходами между представлениями 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 из двух кнопок. Когда параметр @StateshowOverlay
изменено это сделано в течение withAnimation
блок. Переходы на отдельных кнопках не соблюдаются.
Если я удалю HStack и помещу zIndex(1) на каждую кнопку, то произойдет переход удаления, но не переход вставки.
Я хочу, чтобы обе кнопки переходили определенным образом, когда их группа добавляется в представление.
Вопросы: почему обертывание в HStack приводит к игнорированию внутренних переходов? Почему краевой переход работает только в одном направлении?
2 ответа
Чтобы получить две разные анимации, вы можете подтянуть условную логику ближе к кнопкам, то есть внутри 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
, но это не должно быть большой проблемой, по крайней мере, в этом примере.
Переход работает для вида, который появился / исчез. В предоставленном коде снимок появился / исчезHStack
, поэтому к нему следует применить переход.
Примечание: переходы необходимо тестировать на симуляторе или реальном устройстве, большинство из них не работают в предварительном просмотре.
Ниже представлена измененная часть кода, которая дает рабочее поведение. Протестировано с Xcode 11.2 / iOS 13.2
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)
}