首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI: NavigationView/NavigationLink:启动目标推送?

问SwiftUI: NavigationView/NavigationLink:启动目标推送?
EN

Stack Overflow用户
提问于 2021-02-27 02:55:46
回答 1查看 540关注 0票数 1

iOS邮件应用程序启动时,您最近查看的邮箱已经被推送到导航堆栈上,尽管它实际上是一个详细的屏幕,根视图控制器是所有邮箱的列表。这在UIKit中是很简单的,因为推到导航控制器上是很简单的,并且可以在viewDidLoad或applicationDidFinishLaunching内部完成。

NavigationView和NavigationLink是在SwiftUI中执行导航推送/pops的API,NavigationLink支持几个模仿编程导航的APIs -但我不太清楚如何能够支持这个特定的用例。每次屏幕出现时都会调用onAppear闭包(更像viewDidAppear而不是viewDidLoad),因此当用户试图弹出时,设置对应于NavigationLink的selection值将导致重复推送详细信息屏幕。我可以尝试对State进行一些黑客操作,以确定屏幕是否刚刚被查看过,但这似乎不太理想。(关于NavigationLink的selection API,我也遇到了一些问题,但这可能是另一个问题。)

有什么建议吗?我如何将应用程序启动到一个详细的屏幕上,但如果没有任何编程干预,NavigationView就能正常运行吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-10 22:34:36

如果不需要在模式或动画中显示视图,则应该使用编程导航( NavigationLink with selection binding )获得所需的行为。

例如,如果它是应用程序的根,那么下面的内容应该可以工作:

代码语言:javascript
复制
struct Item: Identifiable {
    let id: Int
    let name: String
}

struct NormalNav: View {
    @State var items: [Item] = [
        .init(id: 0, name: "One"),
        .init(id: 1, name: "Two"),
        .init(id: 2, name: "Three")
    ]

    @State private var selection: Int? = 1

    var body: some View {
        NavigationView {
            List {
                ForEach(items) { item in
                    NavigationLink(item.name,
                                   destination: Text(item.name),
                                   tag: item.id,
                                   selection: $selection)
                }
            }
        }
    }
}

上面的视图应该直接打开到没有动画的第二项(“两个”)。

不过,还是有皱纹的。如果您需要在工作表中显示此视图,则使用动画推送详细视图,这可能不是您想要的结果。

在this answer的基础上,您可以在初始创建过程中禁用动画,但将其打开以供后续导航:

代码语言:javascript
复制
struct ContentView: View {
    @State var items: [Item] = [
        .init(id: 0, name: "One"),
        .init(id: 1, name: "Two"),
        .init(id: 2, name: "Three")
    ]

    @State private var selection: Int? = nil
    @State var isAnimationDisabled = true
    @State var isListPresented = false

    var body: some View {
        Button("Show list") {
            isListPresented = true
        }.sheet(isPresented: $isListPresented) {
            NavigationView {
                List {
                    ForEach(items) { item in
                        NavigationLink(item.name,
                                       destination: Text(item.name),
                                       tag: item.id,
                                       selection: $selection)
                    }
                }.animations(disabled: isAnimationDisabled)
            }.onChange(of: selection) { value in
                if value == nil {
                    isAnimationDisabled = false
                }
            }.onAppear {
                selection = 1
            }
        }
    }
}

extension View {
    func animations(disabled: Bool) -> some View {
        transaction { (tx: inout Transaction) in
            guard disabled else {
                return
            }
            tx.disablesAnimations = true
            tx.animation = .none
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66395168

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档