如何将可选视图传递给 SwiftUI 中的另一个视图?

Posted

技术标签:

【中文标题】如何将可选视图传递给 SwiftUI 中的另一个视图?【英文标题】:How to pass optional view to another view in SwiftUI? 【发布时间】:2021-11-26 11:04:42 【问题描述】:

所以我有这个TestView,它接受headerContentbodyContent

struct TestView<Content: View>: View 
  let headerContent: (() -> Content)?  = nil
  let bodyContent: () -> Content
  
  var body: some View 
    VStack 
      headerContent?()
      bodyContent()
    

  

我把它用作,

struct ContentView: View   
  var body: some View 
    TestView 
      Text("Body Content")
    
  

现在,我如何传递headerContent?我试过了,

struct ContentView: View   
  var body: some View 
    TestView(headerContent: 
      Text("HeaderContent")
    ) 
      Text("BodyContent")
    
  

我得到错误,

Extra arguments at positions #1, #2 in call
Generic parameter 'Content' could not be inferred

【问题讨论】:

【参考方案1】:

方式1:

这是一种方法,但如果您的 headerView 类型与正文内容不同,您会遇到问题和错误!例如。圆圈和文本。我用第二种方式解决了这个问题:

struct TestView<Content: View>: View 
    
    @ViewBuilder let headerContent: (() -> Content)?
    @ViewBuilder let bodyContent: () -> Content
    
    init(headerContent: (() -> Content)? = nil, bodyContent: @escaping () -> Content) 
        self.headerContent = headerContent
        self.bodyContent = bodyContent
    
    
    var body: some View 
        
        return VStack 
            
            headerContent?()
            bodyContent()
        
        
    
    


方式2:

这是适合您的正确方法:

struct TestView<BodyContent: View, HeaderContent: View>: View 
    
    @ViewBuilder let headerContent: () -> HeaderContent
    @ViewBuilder let bodyContent: () -> BodyContent
    
    init(headerContent: @escaping () -> HeaderContent, bodyContent: @escaping () -> BodyContent) 
        self.headerContent = headerContent
        self.bodyContent = bodyContent
    
    
    init(bodyContent: @escaping () -> BodyContent) where HeaderContent == EmptyView 
        self.headerContent =  EmptyView() 
        self.bodyContent = bodyContent
    
    
    var body: some View 
        
      return VStack 
            
            headerContent()
            
            bodyContent()
        
        
    

用例:

struct ContentView: View 
    
    var body: some View 
          
        TestView(headerContent: 
            Circle().fill(Color.red).frame(width: 25, height: 25)
        , bodyContent: 
            Text("Hello, World!")
        )
            

        TestView(bodyContent: 
            Text("Hello, World!")
        )

    
    

【讨论】:

【参考方案2】:

只需将其设为var(即可更改)而不是let,就像

struct TestView<Content: View>: View 
  var headerContent: (() -> Content)?  = nil     // << here !!

...

【讨论】:

@swiftPunk,上下文没有问题。【参考方案3】:

将可选变量从 let 更改为 var

当您使用let 关键字定义变量时,您无法更改它。在您的示例中,您已将 nil 设置为 headerContent 的常量。

struct TestView<Content: View>: View 
    var headerContent: (() -> Content)?  = nil
    let bodyContent: () -> Content

您还可以将letinit 一起使用

struct TestView<Content: View>: View 
    let headerContent: (() -> Content)?
    let bodyContent: () -> Content
    
    init(headerContent: (() -> Content)?  = nil, bodyContent: @escaping () -> Content) 
        self.headerContent = headerContent
        self.bodyContent = bodyContent
    

【讨论】:

以上是关于如何将可选视图传递给 SwiftUI 中的另一个视图?的主要内容,如果未能解决你的问题,请参考以下文章

将可选枚举传递给 VB.NET 中的函数

reactjs中如何将可选元素作为prop传递给组件

如何将可选 ID 从 Route 传递给 Laravel 控制器?

我们如何在 SwiftUi 的另一个视图中传递布尔状态

将可选列表传递给 argparse

如何将通用视图传递给 SwiftUI 中的结构