将具有自己参数的 SwiftUI 视图作为变量传递给另一个视图结构

Pass a SwiftUI view that has its own arguments as a variable to another view struct

我会尝试在这里概述我的情况,我有一个 NavigationLink 我想变成它自己的结构,以便我可以重新使用它。 NavigationLink 内的 Label 对于我使用的所有案例都是相同的,只是不同的文本和图像。我正在尝试使包含 NavigationLink 的新结构有一个用于 NavigationLink.

的目标视图的参数

我发现这个 link 让我走了大部分路,但我似乎无法完成最后一英里。

如何将一个 SwiftUI 视图作为变量传递给另一个视图结构

这是我制作的可重复使用的 NavigationLink 结构:

struct MainMenuButtonView<Content: View>: View {
    
    var imageName: String
    var title: String
    var description: String
    var content: Content
    
    init(@ViewBuilder content: @escaping () -> Content) {
        self.content = content()
    }
    
    var body: some View {
        VStack {
            NavigationLink(destination: content) {
                Image(imageName)
                    .resizable()
                    .frame(width: 100, height: 100)
                Text(title)
                    .font(.title)
                Text(description)
                    .foregroundColor(Color(UIColor.systemGray2))
                    .multilineTextAlignment(.center)
                    .font(.footnote)
                    .frame(width: 175)
            }
            .buttonStyle(PlainButtonStyle())
        }
    }
}

我目前在这部分没有发现任何错误,但这并不意味着它没有问题。

这里是我正在使用它的地方,目前,我只展示了一个,但一旦我开始工作,我就会有更多。

struct MainMenuView: View {
    
    var body: some View {
        NavigationView {
            MainMenuButtonView(imageName: "List Icon",
                               title: "Lists",
                               description: "Auto generated shopping lists by store",
                               content: TestMainView(testText: "Lists"))
            }
            .buttonStyle(PlainButtonStyle())
            .navigationBarTitle(Text("Main Menu"))
        }
    }
}

当我像上面那样保留它时,它告诉我有一个额外的参数并且无法推断出'Contect'。 Xcode 确实提供了一个修复程序,在我完成修复后它最终看起来像这样

MainMenuButtonView<Content: View>(imageName: "List Icon",

但随后我得到一个错误,它无法在范围内找到 'Content'。我知道我的问题与我在上面 link 编辑的示例之间的主要区别是我传递的视图也有参数。我不确定我是否也应该将所有参数放在 <> 内的标注中。

感谢您提供的任何帮助。

您需要更正 MainMenuButtonView 中的 init:

struct MainMenuButtonView<Content: View>: View {
    var imageName: String
    var title: String
    var description: String
    var content: () -> Content // change to closure

    // add all parameters in the init
    init(imageName: String, title: String, description: String, @ViewBuilder content: @escaping () -> Content) {
        self.imageName = imageName // assign all the parameters, not only `content`
        self.title = title
        self.description = description
        self.content = content
    }

    var body: some View {
        VStack {
            NavigationLink(destination: content()) { // use `content()`
                Image(imageName)
                    .resizable()
                    .frame(width: 100, height: 100)
                Text(title)
                    .font(.title)
                Text(description)
                    .foregroundColor(Color(UIColor.systemGray2))
                    .multilineTextAlignment(.center)
                    .font(.footnote)
                    .frame(width: 175)
            }
            .buttonStyle(PlainButtonStyle())
        }
    }
}

此外,您需要将 闭包 传递给 content 参数(如您在 init 中指出的那样):

struct MainMenuView: View {
    var body: some View {
        NavigationView {
            MainMenuButtonView(
                imageName: "List Icon",
                title: "Lists",
                description: "Auto generated shopping lists by store",
                content: { TestMainView(testText: "Lists") } // pass as a closure
            )
            .navigationBarTitle(Text("Main Menu"))
        }
    }
}