如何复制NavigationView过渡

时间:2020-09-07 20:34:44

标签: swift swiftui

我正在尝试复制NavigationView和NavigationLink的功能(因为我需要更多的灵活性,并且NavigationBar不能满足我的设计需求),但是我无法正确获取视图过渡。

我具有以下组成部分:

  • RouterState,可跟踪视图堆栈并具有推入和弹出视图的功能。
  • Router呈现视图堆栈并向后代提供路由器状态。
  • Link,它将视图推入堆栈。
  • LinkBack,它将从堆栈中弹出视图。

所有这些均按预期工作。问题是使视图内外动画化。当我在视图中添加Transition.moveTransition.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())
    }
}

0 个答案:

没有答案