我正在实现一个名为MenuItemvery定制NavigationLink,并希望在整个项目中重用它.它是一个符合View的 struct ,实现了包含NavigationLinkvar body : some View.

我在MenuItem的正文中将destinationView定义为some View,并try 了两个初始值设定项:

这似乎太容易了:

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.

第二次try :

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...
    }
}

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

最后一次try :

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...
    }
}

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

我希望有人能帮助我.如果NavigationLink可以接受某些视图作为参数,那么肯定有办法.

推荐答案

总结一下我在这里读到的一切,以及对我有效的解决方案:

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

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

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:

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

如果视图中需要初始值设定项,那么也可以使用@ViewBuilder作为参数.即使对于多个参数,如果您愿意:

init(@ViewBuilder content: () -> Content) {…}

Swift相关问答推荐

字符串目录不适用于SWIFT包

.onReceive NSWindow.CloseNotify是否会为App中的每个窗口调用?

减go 用SWIFT struct 填充的NSCountedSet

在`NavigationStack`中使用`SafeAreaInset`修饰符时出现SwiftUI异常行为

格式化单位和度量值.为什么从符号初始化的单位不能产生与静态初始化相同的结果

对实例方法appendInterpolation的调用没有完全匹配

Swift ui 转换无法按预期工作

是否可以使用一个 NSRegularExpression 同时判断字符串格式并提取子字符串?

除法中如果除以完全因数需要更长时间吗?

MacOS KIND 是如何实现的

如何为 Swift UI 视图定义 struct ?

Xcode:方法参数的代码完成

如何以快速 Select 器菜单样式调整图像大小

swift:修改字典中的数组

当我必须在 Swift 中的类、 struct 和枚举之间进行 Select 时,我应该如何推理?

swift : 具有类型和值的枚举常量

Swift中switch 盒的详尽条件

在 unwind segue 之后执行 push segue

如何在 Swift 中将 NSURL 转换为字符串

键盘显示时Tableview滚动内容