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

查看:27
本文介绍了如何将一个 SwiftUI 视图作为变量传递给另一个视图结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实施一个名为 MenuItem非常 自定义 NavigationLink,并希望在整个项目中重复使用它.它是一个符合 View 并实现 var body : some View 的结构体,其中包含一个 NavigationLink.我需要以某种方式将 NavigationLink 应呈现的视图存储在 MenuItem 的主体中,但尚未这样做.

I'm implementing a very custom NavigationLink called MenuItem and would like to reuse it across the project. It's a struct that conforms to View and implements var body : some View which contains a NavigationLink. I need to somehow store the view that shall be presented by NavigationLink in the body of MenuItem but have yet failed to do so.

我在 MenuItem 的主体中定义了 destinationViewsome View 并尝试了两个初始化程序:

I have defined destinationView in MenuItem's body as some View and tried two initializers:

这似乎太简单了:

struct MenuItem: View {
    private var destinationView: some View

    init(destinationView: View) {
        self.destinationView = destinationView
    }

    var body : some View {
        // Here I'm passing destinationView to NavigationLink...
    }
}

--> 错误: 协议视图"只能用作通用约束,因为它具有自身或相关的类型要求.

--> Error: Protocol 'View' can only be used as a generic constraint because it has Self or associated type requirements.

第二次尝试:

struct MenuItem: View {
    private var destinationView: some View

    init<V>(destinationView: V) where V: View {
        self.destinationView = destinationView
    }

    var body : some View {
        // Here I'm passing destinationView to NavigationLink...
    }
}

--> 错误: 无法将V"类型的值分配给some View"类型.

--> Error: Cannot assign value of type 'V' to type 'some View'.

最后的尝试:

struct MenuItem: View {
    private var destinationView: some View

    init<V>(destinationView: V) where V: View {
        self.destinationView = destinationView as View
    }

    var body : some View {
        // Here I'm passing destinationView to NavigationLink...
    }
}

--> 错误: 无法将View"类型的值分配给some View"类型.

--> Error: Cannot assign value of type 'View' to type 'some View'.

我希望有人能帮助我.如果 NavigationLink 可以接受某些 View 作为参数,则必须有一种方法.谢谢;D

I hope someone can help me. There must be a way if NavigationLink can accept some View as an argument. Thanks ;D

推荐答案

总结一下我在这里读到的所有内容以及对我有用的解决方案:

To sum up everything I read here and the solution which worked for me:

struct ContainerView<Content: View>: View {
    @ViewBuilder var content: Content
    
    var body: some View {
        content
    }
}

这不仅可以让你把简单的 View 放在里面,而且,感谢 @ViewBuilder,使用 if-elseswitch-case 块:

This not only allows you to put simple Views inside, but also, thanks to @ViewBuilder, use if-else and switch-case blocks:

struct SimpleView: View {
    var body: some View {
        ContainerView {
            Text("SimpleView Text")
        }
    }
}

struct IfElseView: View {
    var flag = true
    
    var body: some View {
        ContainerView {
            if flag {
                Text("True text")
            } else {
                Text("False text")
            }
        }
    }
}

struct SwitchCaseView: View {
    var condition = 1
    
    var body: some View {
        ContainerView {
            switch condition {
            case 1:
                Text("One")
            case 2:
                Text("Two")
            default:
                Text("Default")
            }
        }
    }
}

奖励:如果你想要一个贪婪的容器,它将要求所有可能的空间(与上面的容器相反,它只要求其子视图所需的空间),它是:

Bonus: If you want a greedy container, which will claim all the possible space (in contrary to the container above which claims only the space needed for its subviews) here it is:

struct GreedyContainerView<Content: View>: View {
    @ViewBuilder let content: Content
    
    var body: some View {
        Color.clear
            .overlay(content)
    }
}

这篇关于如何将一个 SwiftUI 视图作为变量传递给另一个视图结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆