标签: swiftui-navigationlink

SwiftUI - 如何避免导航硬编码到视图中?

我尝试为更大的、可用于生产的 SwiftUI 应用程序构建架构。我一直在遇到同样的问题,这指向 SwiftUI 中的一个主要设计缺陷。

仍然没有人能给我一个完整的工作,生产就绪的答案。

如何做SwiftUI包含导航的可重用视图?

由于它SwiftUI NavigationLink与视图有很强的联系,这根本不可能以这样的方式在更大的应用程序中扩展。NavigationLink在那些小样本应用程序中,是的 - 但不是当您想在一个应用程序中重用许多视图时。也可能在模块边界上重用。(例如:在 iOS、WatchOS 等中重用 View...)

设计问题:导航链接被硬编码到视图中。

NavigationLink(destination: MyCustomView(item: item))
Run Code Online (Sandbox Code Playgroud)

但是如果包含这个的视图NavigationLink应该是可重用的,我就不能对目的地进行硬编码。必须有一种机制来提供目的地。我在这里问了这个问题并得到了很好的答案,但仍然不是完整的答案:

SwiftUI MVVM 协调器/路由器/导航链接

这个想法是将目标链接注入可重用视图。一般来说,这个想法可行,但不幸的是,这并不能扩展到真正的生产应用程序。一旦我有多个可重用的屏幕,我就会遇到一个逻辑问题,即一个可重用的视图 ( ViewA) 需要一个预配置的视图目标 ( ViewB)。但是如果ViewB还需要一个预配置的 view-destinationViewC呢?我需要建立ViewB在这样的方式已经ViewC被注入已经ViewB在我注入ViewBViewA。等等......但由于当时必须传递的数据不可用,整个构造失败。

我的另一个想法是使用Environmentas 依赖注入机制为NavigationLink. 但我认为这或多或少应该被视为一种黑客行为,而不是大型应用程序的可扩展解决方案。我们最终会基本上将环境用于所有事情。但是因为 Environment 也只能在 View 内部使用(而不是在单独的 Coordinators 或 ViewModels 中),所以在我看来这将再次创建奇怪的构造。

就像业务逻辑(例如视图模型代码)和视图必须分开,导航和视图也必须分开(例如协调器模式)UIKit因为我们访问视图UIViewControllerUINavigationController …

xcode ios swift swiftui swiftui-navigationlink

109
推荐指数
6
解决办法
8034
查看次数

SwiftUI NavigationView 试图弹出到丢失的目的地(Monoceros?)

我正在使用 Xcode 12 进行 iOS 14.0 的部署。

  • 我的主屏幕有一个 NavigationView
  • 在 NavigationView 中有一个 TabView(有 4 个选项卡)
  • 每个选项卡中都有包含按钮和导航链接的子视图

应用程序上的导航功能正常(当我单击其中一个子视图上的 NavigationLink 时,它导航到正确的视图,当我单击后退按钮时,它会关闭视图。)但是,当我单击后退按钮时,控制台打印以下错误:

Trying to pop to a missing destination at /Library/Caches/com.apple.xbs/Sources/Monoceros/Monoceros-103/Shared/NavigationBridge_PhoneTV.swift:337
Run Code Online (Sandbox Code Playgroud)

除了错误日志之外,该应用程序运行良好,所以我打算暂时忽略该错误......但我想知道它意味着什么?我的代码中没有任何名为“Monoceros”的内容。我猜这与 TabView 作为 NavigationView 的子视图有关?

编辑:

几个月后,这个问题仍然存在。这是可重现的代码。打开 ContentView(),在 FirstScreen() 上单击 NavigationLink,然后单击后退按钮。它会打印出 Monoceros 哈哈

Trying to pop to a missing destination at /Library/Caches/com.apple.xbs/Sources/Monoceros/Monoceros-103/Shared/NavigationBridge_PhoneTV.swift:337
Run Code Online (Sandbox Code Playgroud)

xcode swift navigationview swiftui swiftui-navigationlink

21
推荐指数
1
解决办法
1849
查看次数

'init(destination:isActive:label:)' 在 iOS 16.0 中已弃用:在 NavigationStack 或 NavigationSplitView 中使用 NavigationLink(value:label:)

我已经尝试了该网站上发布的示例的不同版本,但没有任何进展。

我也尝试过遵循此处列出的示例:

导航到新的导航类型:

我在这篇文章的标题中收到关于弃用 NavigationLink(destination:isActive) 的警告

struct PhoneLogin: View {
    @StateObject var phoneLoginData = PhoneLoginViewModel()
    @State var isSmall = UIScreen.main.bounds.height < 750
    
    var body: some View {
        VStack {
            VStack {
                Text("Continue With Phone")
                    .font(.title2)
                    .fontWeight(.bold)
                    .foregroundColor(.black)
                    .padding()
                
                Image("phone_logo")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .padding()
                
                Text("You'll receive a 4-digit code \n to verify next")
                    .font(isSmall ? .none : .title2)
                    .foregroundColor(.gray)
                    .multilineTextAlignment(.center)
                    .padding()
                
                // Mobile Number Field . . . . .
                
                HStack {
                    VStack(alignment: .leading, spacing: 6) {
                        Text("Enter Your Number")
                            .font(.caption) …
Run Code Online (Sandbox Code Playgroud)

deprecation-warning swiftui-navigationlink ios16 xcode14

21
推荐指数
1
解决办法
1万
查看次数

如何禁用 NavigationView 推送和弹出动画

鉴于这个简单NavigationView

struct ContentView : View {
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink("Push Me", destination: Text("PUSHED VIEW"))
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

NavigationView当目标视图被推入/弹出堆栈时,有没有人找到禁用动画的方法?

从 iOS2.0 开始,这在 UIKit 中已经成为可能!我认为从框架中提出的要求并不过分。我在所有视图上尝试了各种修饰符(即NavigationView容器、目标视图NavigationLink、 等)

这些是我尝试过的一些修饰符:

.animation(nil)
Run Code Online (Sandbox Code Playgroud)
.transition(.identity)
Run Code Online (Sandbox Code Playgroud)
.transaction { t in t.disablesAnimations = true }
Run Code Online (Sandbox Code Playgroud)
.transaction { t in t.animation = nil }
Run Code Online (Sandbox Code Playgroud)

没有任何区别。我没有发现任何有用的东西EnvironmentValues:-(

我是否遗漏了一些非常明显的东西,或者功能还不存在?

swiftui swiftui-navigationlink swiftui-navigationview

20
推荐指数
3
解决办法
4263
查看次数

NavigationLink isActive 已弃用

在新版本的iOS和Xcode中

NavigationLink(isActive: , destination: , label: ) 
Run Code Online (Sandbox Code Playgroud)

已弃用。

那么我们如何控制NavigationLink的状态呢?

swiftui swiftui-navigationlink

18
推荐指数
2
解决办法
2万
查看次数

如何修复 Xcode 14 警告:呈现值的 NavigationLink 必须出现在基于 NavigationContent 的 NavigationView 内。链接将被禁用

自从安装 Xcode 14 以来,我现在在控制台中打印以下错误消息:

呈现值的 NavigationLink 必须出现在基于 NavigationContent 的 NavigationView 内。链接将被禁用。

我的应用程序的结构如下:

  1. 我将视图 A 包裹在导航视图中。导航视图内部有一个链接到视图 B 的导航链接。

  2. 我的视图 B 没有导航视图,但有一个指向视图 C 的导航链接。视图 B 继承了视图 A 中定义的导航视图

当我按下视图 B 上的后退按钮,弹出回视图 A 时,会打印警告。当我将视图 B 包装在导航视图中时,警告消失,但这当然现在在两个导航视图中显示视图 B,这不是什么我想。

我不确定为什么会打印此警告,因为视图 ​​B 继承了视图 A 中定义的 NavigationView。

swiftui swiftui-navigationlink swiftui-navigationview ios16 xcode14

17
推荐指数
3
解决办法
1万
查看次数

SwiftUI .toolbar disappears after following NavigationLink and coming back

I've added a .toolbar to the top level of a NavigationView that will eventually be used to select items in a list without using swipe gestures (up button, down button, etc.). I also have a .navigationBar going on, to access other views for Account and Settings.

For the most part it's looking really good, but when I follow a NavigationLink (in .navigationBarItems) within NavigationView, and then use the built-in back navigation, my .toolbar disappears from the top level.

Am …

swiftui swiftui-navigationlink swiftui-navigationview

15
推荐指数
1
解决办法
1157
查看次数

SwiftUI:添加 .onDrag 阻止单击/选择 macOS 侧栏中的项目

我的 macOS app\xe2\x80\x99s 侧边栏中有一个列表。当我添加.onDrag修改器时,拖动NSItemProvider可以正常工作,但单击/选择项目会触发被阻止NavigationLink

\n
struct ContentView: View {\n    var body: some View {\n        NavigationView {\n            List(Data.items) { item in\n                NavigationLink(\n                    destination: Text(item.text),\n                    label: {\n                        Text(item.text)\n                          .lineLimit(5)\n                           // Enabling dragging with .onDrag {} disables click and selection:\n                          .onDrag { return NSItemProvider(object: item.url as NSURL) }\n                    })\n            }\n            Text("Placeholder")\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

如何添加拖动行为,同时保持正常的列表选择行为不变?

\n

这是最小可重现示例的其余部分:

\n
import SwiftUI\n\n@main\nstruct ListDragExampleApp: App {\n    var body: some Scene {\n        WindowGroup {\n            ContentView()\n        }\n    }\n}\n\nstruct Data {\n    struct Item: …
Run Code Online (Sandbox Code Playgroud)

swiftui swiftui-list swiftui-navigationlink

14
推荐指数
1
解决办法
938
查看次数

创建一个 SwiftUI 侧边栏

我想使用 SwiftUI 构建一个非常简单的 iOS 14 侧边栏。该设置是相当简单,我有三个观点HomeViewLibraryViewSettingsView和枚举代表每个屏幕。

enum Screen: Hashable {
   case home, library, settings
}
Run Code Online (Sandbox Code Playgroud)

我的最终目标是根据大小类在选项卡视图和侧边栏之间自动切换,但有些事情并没有按预期工作。

全局状态由 拥有MainNavigationView,它也是 my 的根视图WindowGroup

struct MainNavigationView: View {
    @State var screen: Screen? = .home
   
    var body: some View {
        NavigationView {
            SidebarView(state: $screen)
        }
        .navigationViewStyle(DoubleColumnNavigationViewStyle())
    }
}
Run Code Online (Sandbox Code Playgroud)

SidebarView是一个简单的List包含三个NavigationLink,每个一个Screen

struct SidebarView: View {
    @Binding var state: Screen?
    var body: some View {
        List {
            NavigationLink(
                destination: HomeView(), …
Run Code Online (Sandbox Code Playgroud)

ios swiftui swiftui-navigationlink

12
推荐指数
1
解决办法
3179
查看次数

在推送视图中修改列表绑定属性时,SwiftUI 导航会弹出

当我从向下推 2+ 层的视图中的数组更新绑定属性时,导航会在属性更改后立即弹出。

Xcode 13.3 测试版、iOS 15。

我创建了一个简单的演示,代码如下。

购物清单 列表编辑 列表部分编辑
购物清单视图 购物清单编辑视图 购物清单编辑部分查看

更新列表标题(一个视图深)就可以了,导航堆栈保持不变,如果我返回,更改就会发布。但是,当调整部分标题(两层深)时,只要我对属性进行一次更改,导航就会弹出。

我有一种感觉,我在这里缺少基本的基础知识,而且我有一种感觉,它一定与列表有关id?但我正在努力弄清楚或解决它。

动图

例子

代码:

楷模:

struct ShoppingList {
    let id: String = UUID().uuidString
    var title: String
    var sections: [ShoppingListSection]
}

struct ShoppingListSection {
    let id: String = UUID().uuidString
    var title: String
}

Run Code Online (Sandbox Code Playgroud)

查看型号:

final class ShoppingListsViewModel: ObservableObject {
    @Published var shoppingLists: [ShoppingList] = [
        .init(
            title: "Shopping List 01",
            sections: [
                .init(title: "Fresh food")
            ]
        )
    ]
}
Run Code Online (Sandbox Code Playgroud)

内容查看:

struct ContentView: View {
    var body: some View …
Run Code Online (Sandbox Code Playgroud)

swiftui swiftui-navigationlink swiftui-navigationview

12
推荐指数
1
解决办法
2704
查看次数