ios - NavigationLink 以编程方式关闭不再适用于 iOS 15

标签 ios swift swiftui

与我们大多数人一样,我将我的 iPhone 更新到了 iOS 15。遗憾的是,我注意到通过 Binding 取消了一个 View 。的NavigationLink不再像在 iOS 14 上那样工作。它适用于第一个链接,但不适用于第二个或更高版本。
iOS 14.5:
enter image description here
iOS 15.0:
enter image description here
我创建了一个重新创建问题的小项目:

import SwiftUI

struct ContentView: View {
    enum NextView: Hashable {
        case view1
    }

    @State private var nextView: NextView?

    var body: some View {
        NavigationView {
            VStack {
                Button("Next", action: { nextView = .view1 })
            }
            .background(Color.red)
            .background(
                NavigationLink(
                    tag: .view1,
                    selection: $nextView,
                    destination: {
                        View1 { dismissReason in
                            nextView = nil
                        }
                    },
                    label: EmptyView.init
                )
            )
        }
    }
}

struct View1: View {
    enum NextView: Hashable {
        case view2
    }

    enum DismissReason {
        case back
    }

    let onDismiss: (DismissReason) -> Void

    @State private var nextView: NextView?

    var body: some View {
        VStack {
            Button("Back", action: { onDismiss(.back) })
            Button("Next", action: { nextView = .view2 })
        }
        .background(Color.yellow)
        .background(
            NavigationLink(
                tag: .view2,
                selection: $nextView,
                destination: {
                    View2 { dismissReason in
                        nextView = nil
                    }
                },
                label: EmptyView.init
            )
        )
    }
}

struct View2: View {
    enum NextView: Hashable {
        case text
    }

    enum DismissReason {
        case back
    }

    let onDismiss: (DismissReason) -> Void

    @State private var nextView: NextView?

    var body: some View {
        VStack {
            Button("Back", action: { onDismiss(.back) })
            Button("Next", action: { nextView = .text })
        }
        .background(Color.green)
        .background(
            NavigationLink(
                tag: .text,
                selection: $nextView,
                destination: { Text("Destination") },
                label: EmptyView.init
            )
        )
    }
}

最佳答案

我可以重现您的错误,坦率地说,您的代码中似乎有一些错误。下面是一个屏幕截图,它取代了 1000 字的解释。
在这里,我们在 View2 中的“后退”按钮被点击后处于断点处。 nextView状态变量已正确设置为 nil .
但是,当我们继续运行时,View2 并没有消失。
基本上,有什么问题(根据我的理解)是,渲染目标的条件是 FALSE(这是正确的),但无论如何,View2 将被绘制 - 分别不会被删除。
请注意,即使条件为假,View2 的主体也会运行。
为什么会这样,以及这是否“合法”或 SwiftUI 中的错误需要在其他地方进行调查。我建议创建一个错误报告并将其提交给 Apple。
enter image description here
更新:
我找到了一种解决方法和导致这种行为的可能原因。对于 iPad 和 iPhone,NavigationLink 的处理方式将有所不同。如果导航 View 样式是 column , 在 iPad 上,我们总是在堆栈上看到第一个 View 和第二个 View 。我们不能弹出“返回”第二个 View ,也没有“返回”按钮。第三个 View 和任何后续插入堆栈的 View 都有一个“后退”按钮,当然可以弹出。
给定代码中的行为似乎在使用“列” View 。
因此,解决此问题的解决方法是在 iPhone 上渲染我建议明确设置 stack作为导航 View 样式:

NavigationView {
    ...
}
.navigationViewStyle(.stack)
否则,对于 iPad,这取决于您希望如何显示导航堆栈 View 。
因此,默认的 NavigationLinkStyle,即 automatic在 iPhone 上运行时确实会显示此问题。我认为这是一个错误,并向 Apple 报告是合理的。
款式columns (仅适用于 iOS 15)不适用于 iPhone。

关于ios - NavigationLink 以编程方式关闭不再适用于 iOS 15,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69296572/

相关文章:

swift - 如何在 SwiftUI 中实现多行 TextView

swift - 类型 '()'不能符合View(除非它肯定是一个View,这次没有恶作剧)

ios - 使用 RxSwift 从 UITableViewCell 发送回调到 UIViewController

iphone - 打字计算器? Xcode

swift - 使用 p 和 g 等字母垂直截断标签中的文本

ios - 读取当前用户的数据?

ios - 如何在 Swift 3 中使用 unsafeDowncast

ios - 与 automaticallyAdjustsScrollViewInsets 的兼容性

ios - 遍历数组并在 Swift 中增加计数器

ios - 来自 Text 的 SwiftUI 背景颜色会忽略安全区域,即使它未设置为忽略