简体   繁体   English

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

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

I'll try to outline my case here, I have a NavigationLink I'm wanting to turn into it's own structure so I can re-use it.我将尝试在这里概述我的案例,我有一个NavigationLink我想变成它自己的结构,以便我可以重复使用它。 The Label inside the NavigationLink is the same for all the cases I'm using, just different text and images. NavigationLink中的Label对于我使用的所有情况都是相同的,只是文本和图像不同。 I'm trying to make that new struct that contains the NavigationLink have an argument I use for the destination View of the NavigationLink .我正在尝试使包含NavigationLink的新结构具有我用于NavigationLink的目标视图的参数。

I found this link that got me most of the way, but I just don't seem to be able to get it the last mile.我发现这个链接让我走了大部分路,但我似乎无法在最后一英里得到它。

How to pass one SwiftUI View as a variable to another View struct 如何将一个 SwiftUI 视图作为变量传递给另一个视图结构

Here is the re-usable NavigationLink struct I made:这是我制作的可重复使用的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())
        }
    }
}

I currently don't get any errors on that part, but that doesn't mean there isn't something wrong with it.我目前在这部分没有收到任何错误,但这并不意味着它没有任何问题。

And here is where I'm using it at, currently, I just shown one, but I'll have more once I get it working.这里是我使用它的地方,目前,我只展示了一个,但一旦我得到它,我会拥有更多。

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"))
        }
    }
}

When I leave it as above, it tells me that there is an extra argument and that 'Contect' can't be inferred.当我把它留在上面时,它告诉我有一个额外的论点并且无法推断出“联系”。 Xcode does offer a fix, and it ends up looking like this after I do the fix Xcode 确实提供了修复,在我修复后它最终看起来像这样

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

But then I get an error that it cannot find 'Content' in scope.但后来我收到一个错误,它在 scope 中找不到“内容”。 I know the main difference between my question and the example I linked above is my View I'm passing in also has arguments.我知道我的问题和我上面链接的示例之间的主要区别是我传入的视图也有 arguments。 I'm not sure if I'm also supposed to put all the arguments in the callout within the <>.我不确定我是否也应该将所有 arguments 放在 <> 内的标注中。

Thank you for any help you can give.感谢您提供的任何帮助。

You need to correct the init in the MainMenuButtonView :您需要更正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())
        }
    }
}

Also, you need to pass a closure to the content parameter (as you indicated in the init ):此外,您需要将闭包传递给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"))
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM