如何创建一个带有输入的闭包结构参数,在 SwiftUI 中返回“some View”而不是“AnyView”?

Posted

技术标签:

【中文标题】如何创建一个带有输入的闭包结构参数,在 SwiftUI 中返回“some View”而不是“AnyView”?【英文标题】:How to create a struct parameter that is a closure with input, returning `some View` instead of `AnyView` in SwiftUI? 【发布时间】:2021-01-20 13:45:08 【问题描述】:

现状:

我正在尝试在 SwiftUI 中创建一个可重用的视图,该视图返回传递给它的另一个视图。目前我正在使用一个返回AnyView 的闭包作为参数。 当我初始化可重用视图时,我传递了一个包含在 AnyView() 中的自定义视图。

目标:

理想情况下,我希望有一种方法可以省略 AnyView() 包装器并按原样传递我的 CustomViewACustomViewB

我的尝试和问题:

我尝试更改闭包参数以返回 some View,但出现以下错误:

'some' 类型仅针对属性和下标的声明类型以及函数的返回类型实现

我已经看到了一些关于 S.O. 的尝试。通过以某种方式使用通用参数来解决这个问题,但我不确定如何在我的情况下实现它,或者它是否可能。另外需要注意的是,闭包需要将 String 作为自己的输入参数。

示例代码:

import SwiftUI

struct ReusableView: View 
    let outputView: (String) -> AnyView
    
    var body: some View 
        outputView("Hello World")
    


struct CustomViewA: View 
    let label: String
    
    init(_ label: String) 
        self.label = label
    
    var body: some View 
        return Text(label)
    


struct CustomViewB: View 
    let label: String
    
    init(_ label: String) 
        self.label = label
    
    var body: some View 
        return HStack
            Text(label)
        
    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ReusableView() 
            AnyView(CustomViewA($0))
        
    

【问题讨论】:

【参考方案1】:

您只需将ReusableView 设为泛型并将闭包的返回类型声明为泛型。

struct ReusableView<Output: View>: View 
    let outputView: (String) -> Output
    
    var body: some View 
        outputView("Hello World")
    


struct ContentView_Previews: PreviewProvider 
    static var previews: some View 
        ReusableView() 
            CustomViewA($0)
        
    

【讨论】:

以上是关于如何创建一个带有输入的闭包结构参数,在 SwiftUI 中返回“some View”而不是“AnyView”?的主要内容,如果未能解决你的问题,请参考以下文章

Swift 完成处理程序 - 转义尾随闭包

使用 Xcode LLDB 控制台在 Swift 中调试闭包

4 .Swift函数|闭包

Swift中带括号的闭包的输入参数

Swift 5:转义闭包捕获'inout'参数

在 Swift 3.0 中的转义闭包中改变自我(结构/枚举)