

Это происходит независимо от стиля анимации или времени. view
.edgesIgnoringSafeArea(.all)
Animating with offset or position
Increasing frame height to frame(height: screenHeight + slideOffset)
Adding padding(.top, slideOffset) to compensate vertical shift
Using a ViewModifier to apply padding conditionally
Manually staged keyframe animation via DispatchQueue, withAnimation, and Даже ключевой фарманиматор < /p>
очистить движение вверх снизу вниз с исчезанием
полностью игнорирует безопасную область (как если бы она не существовала)
работает на каждом переходе
не накапливает дополнительную набивку или не вызывает смещения < /p>
.
Код: Выделить всё
import SwiftUI
struct NRoot: View {
@Binding var activeView: String
let views: [(key: String, view: AnyView)]
@State private var currentViewKey: String
@State private var previousViewKey: String?
@State private var isAnimating: Bool = false
@State private var isFirstTransition = true
@State private var opacity: Double = 1
@State private var offset: CGFloat = 0
init(
activeView: Binding,
views: [(key: String, view: any RoutableView)]
) {
self._activeView = activeView
self.views = views.map {(key: $0.key, view: $0.view.toAnyView())}
self._currentViewKey = State(initialValue: activeView.wrappedValue)
}
var body: some View {
GeometryReader { geometry in
let screenHeight = geometry.size.height
let slideOffset = screenHeight * 0.1
ZStack {
if let previousKey = previousViewKey,
let previousView = views.first(where: { $0.key == previousKey }) {
previousView.view
.background(Color(.systemBackground))
.edgesIgnoringSafeArea(.all)
.zIndex(0)
}
if let currentView = views.first(where: { $0.key == currentViewKey }) {
currentView.view
.opacity(opacity)
.offset(y: offset)
.edgesIgnoringSafeArea(.all)
.background(Color(.systemBackground))
.zIndex(1)
}
}
.ignoresSafeArea()
.onChange(of: activeView) { newKey in
guard newKey != currentViewKey else { return }
previousViewKey = currentViewKey
currentViewKey = newKey
isAnimating = true
isFirstTransition = false
opacity = 0
offset = slideOffset
withAnimation(.easeOut(duration: 5)) {
opacity = 1
offset = 0
}
DispatchQueue.main.asyncAfter(deadline: .now() + 5) {
previousViewKey = nil
isAnimating = false
}
}
}
}
}
Подробнее здесь: https://stackoverflow.com/questions/796 ... r-position