我正在尝试复制NavigationView和NavigationLink的功能(因为我需要更多的灵活性,并且NavigationBar不能满足我的设计需求),但是我无法正确获取视图过渡。
我具有以下组成部分:
RouterState
,可跟踪视图堆栈并具有推入和弹出视图的功能。Router
呈现视图堆栈并向后代提供路由器状态。Link
,它将视图推入堆栈。LinkBack
,它将从堆栈中弹出视图。所有这些均按预期工作。问题是使视图内外动画化。当我在视图中添加Transition.move
或Transition.slide
时,动画是混乱的,所有孩子似乎都以某种奇怪的方式重新定位(而不是我想要的幻灯片)。我还尝试了简单地使用偏移动画,该动画在出现视图时有效,而在消失时则不起作用。目标是在单击Link
时从后缘滑入视图,而在单击LinkBack
时以相同的方式滑出。
当前实施:
import Foundation
import SwiftUI
import Combine
class RouterState: ObservableObject {
@Published var stack: [StackElement] = []
func push(content: AnyView) {
stack.append(StackElement(id: stack.count, content: content))
}
func pop() {
_ = self.stack.removeLast()
}
struct StackElement: Identifiable {
let id: Int
let content: AnyView
}
}
struct Router<Content: View>: View {
@ObservedObject var routerState: RouterState = RouterState()
init(@ViewBuilder content: () -> Content) {
routerState.push(content: AnyView(content()))
}
var body: some View {
ZStack {
ForEach(routerState.stack) {
$0.content
}
.background(Color.black)
// Add transition here?
}
.environmentObject(routerState)
}
}
struct Link<Content1: View, Content: View>: View {
@EnvironmentObject var router: RouterState
var destination: AnyView
var content: Content1
init(destination: Content, @ViewBuilder content: () -> Content1) {
self.destination = AnyView(destination)
self.content = content()
}
var body: some View {
Button(action: { self.router.push(content: self.destination) }) {
content
}
}
}
struct LinkBack<Content: View>: View {
@EnvironmentObject var router: RouterState
var content: Content
init(@ViewBuilder content: () -> Content) {
self.content = content()
}
var body: some View {
Button(action: { self.router.pop() }) {
content
}
.buttonStyle(PlainButtonStyle())
}
}