首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >SwiftUI:如何通过NavigationLink将动态生成的参数传递给子视图?

SwiftUI:如何通过NavigationLink将动态生成的参数传递给子视图?
EN

Stack Overflow用户
提问于 2021-04-22 13:36:09
回答 2查看 605关注 0票数 1

我想把三个链接放在一个NavigationView中。

"room.A"

  • Second链接:显示具有特定房间ID的RoomView,显示具有特定房间ID的RoomView,“room .B”

  • 第三链接:在用户单击时显示带有随机生成的房间ID的RoomView。

下面的代码无法工作,因为SwiftUI在构建NavigationView时调用UUID()NavigationView并重用它。

当用户单击链接时,我想生成一个新的随机房间ID,但我无法弄清楚如何做到这一点。我正在寻找一种简单而自然的方式来实现这一点。

代码语言:javascript
运行
复制
import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: RoomView(roomId: "room.A")) {
                    Text("Enter Room A")
                }
                NavigationLink(destination: RoomView(roomId: "room.B")) {
                    Text("Enter Room B")
                }
                NavigationLink(destination: RoomView(roomId: UUID().uuidString)) {
                    Text("Create a new Room and enter")
                }
            }
        }
    }
}

struct RoomView: View {
    let roomId: String
    var body: some View {
        Text("Room View \(roomId)")
    }
}
EN

回答 2

Stack Overflow用户

发布于 2021-04-22 15:14:26

我找到了一个简单的解决方案,但这暴露了SwiftUI的怪异之处。这段代码和上面的代码在逻辑上是相同的,但是由于SwiftUI的优化,它们的行为有所不同。

代码语言:javascript
运行
复制
import SwiftUI

struct ContentView: View {
    var body: some View {
        NavigationView {
            VStack {
                NavigationLink(destination: RoomView(roomId: "room.A")) {
                    Text("Enter Room A")
                }
                NavigationLink(destination: RoomView(roomId: "room.B")) {
                    Text("Enter Room B")
                }
                NavigationLink(destination: NewRoomView()) {
                    Text("Create a new Room and enter")
                }
            }
        }
        .navigationViewStyle(StackNavigationViewStyle())
    }
}

struct NewRoomView: View {
    var body: some View {
        RoomView(roomId: UUID().uuidString)
    }
}
票数 2
EN

Stack Overflow用户

发布于 2021-04-22 14:02:11

这是因为导航链接是急切地执行的。我创建了一个视图,可以在tap上运行创建。

代码语言:javascript
运行
复制
import SwiftUI

struct LazyView<Content>: View where Content: View {

    private let viewBuild: () -> Content

    fileprivate init(_ viewBuild: @escaping () -> Content) {
        self.viewBuild = viewBuild
    }

    init(_ viewBuild: @escaping @autoclosure () -> Content) {
        self.init(viewBuild)
    }

    var body: some View {
        viewBuild()
    }

}

extension NavigationLink {

    init<V>(lazyDestination: @escaping @autoclosure () -> V, @ViewBuilder label: () -> Label) where Destination == LazyView<V> {
        self.init(destination: LazyView(lazyDestination), label: label)
    }

    init<V>(lazyDestination: @escaping @autoclosure () -> V, isActive: Binding<Bool>, @ViewBuilder label: () -> Label)
    where Destination == LazyView<V> {
        self.init(destination: LazyView(lazyDestination), isActive: isActive, label: label)
    }

    init<V, T>(lazyDestination: @escaping @autoclosure () -> V, tag: T, selection: Binding<T?>, @ViewBuilder label: () -> Label)
    where T : Hashable, Destination == LazyView<V> {
        self.init(destination: LazyView(lazyDestination), tag: tag, selection: selection, label: label)
    }

}

extension NavigationLink where Label == Text {

    init<V>(_ titleKey: LocalizedStringKey, lazyDestination: @escaping @autoclosure () -> V) where Destination == LazyView<V> {
        self.init(titleKey, destination: LazyView(lazyDestination))
    }

    init<V, S>(_ title: S, lazyDestination: @escaping @autoclosure () -> V) where S : StringProtocol, Destination == LazyView<V> {
        self.init(title, destination: LazyView(lazyDestination))
    }

    init<V>(_ titleKey: LocalizedStringKey, lazyDestination: @escaping @autoclosure () -> V, isActive: Binding<Bool>)
    where Destination == LazyView<V> {
        self.init(titleKey, destination: LazyView(lazyDestination), isActive: isActive)
    }

    init<V, S>(_ title: S, lazyDestination: @escaping @autoclosure () -> V, isActive: Binding<Bool>)
    where S : StringProtocol, Destination == LazyView<V>  {
        self.init(title, destination: LazyView(lazyDestination), isActive: isActive)
    }

    init<V, T>(_ titleKey: LocalizedStringKey, lazyDestination: @escaping @autoclosure () -> V, tag: T, selection: Binding<T?>)
    where T : Hashable, Destination == LazyView<V> {
        self.init(titleKey, destination: LazyView(lazyDestination), tag: tag, selection: selection)
    }

    init<V, S, T>(_ title: S, lazyDestination: @escaping @autoclosure () -> V, tag: T, selection: Binding<T?>)
    where S : StringProtocol, T : Hashable, Destination == LazyView<V> {
        self.init(title, destination: LazyView(lazyDestination), tag: tag, selection: selection)
    }
}

然后,在您的代码中,用

代码语言:javascript
运行
复制
NavigationLink(lazyDestination: RoomView(roomId: UUID().uuidString)) {
                    Text("Create a new Room and enter")
                }
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67214370

复制
相关文章

相似问题

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