当前位置: 首页 > 知识库问答 >
问题:

Swiftui-可重用的组件,其中链接到其他视图作为参数

阴凯歌
2023-03-14

我想在我的应用程序中创建可重用的组件。

我也找过类似的问题。但我只找到了复杂得多的例子。

让我们试试这个简单的例子--一个按钮,它可以根据传递的参数打开不同的视图。我有两个视图,我将打开作为一张表:

FirstView.Swift

import SwiftUI

struct FirstView: View {
    var body: some View {
        Text("First view")
    }
}

SecondView.Swift

struct SecondView: View {
    var body: some View {
        Text("Second view")
    }
}

ButtonView.swift这是一个视图,我想在我的设计系统中作为可重用的组件使用。

import SwiftUI

struct ButtonView: View {

    @State private var showModal: Bool = false
    
    // This works
    var text: String
    // Here I am getting an error:
    // Protocol 'View' can only be used as a generic constraint because it has Self or associated type requirements
    var link: View
    
    var body: some View {
        VStack {
            Spacer()
            Button(action: {
                self.showModal = true
            }) {
                Text(text)
                    .padding(20)
                    .foregroundColor(Color.white)
            }.sheet(isPresented: self.$showModal) {
                link
            }
            .background(Color.blue)
        }
    }
}

struct ButtonView_Previews: PreviewProvider {
    static var previews: some View {
        ButtonView(text: "TEST", link: FirstView())
    }
}

在这里我尝试使用相同的按钮组件,但带有不同的标签和链接。

import SwiftUI

struct ContentView: View {
    var body: some View {
        HStack {
            ButtonView(text: "first", link: FirstView())
                .padding()
            ButtonView(text: "second", link: SecondView())
                .padding()
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

传递字符串参数起作用。标签是不同的。但我不能使它与不同的视图的链接工作。我得到一个错误:

协议“View”只能用作泛型约束,因为它具有自身或关联的类型要求

共有1个答案

戚泰
2023-03-14

将第一视图和第二视图保持相同,对ButtonView使用以下操作:

struct ButtonView<Content : View>: View {

    @State private var showModal: Bool = false
    
    var text: String
 
    // This is the generic content parameter
    let content: Content
    
    init(text: String, @ViewBuilder contentBuilder: () -> Content){
        self.text = text
        self.content = contentBuilder()
    }
    
    var body: some View {
        VStack {
            Spacer()
            Button(action: {
                self.showModal = true
            }) {
                Text(text)
                    .padding(20)
                    .foregroundColor(Color.white)
            }.sheet(isPresented: self.$showModal) {
                content
            }
            .background(Color.blue)
        }
    }
}

这里,名为content的泛型参数用于接收任何视图,初始化器与@ViewBuilder属性包装一起用于构建视图。现在,在ContentView结构中以以下方式使用它:

struct ContentView: View {
    var body: some View {
        HStack {
            ButtonView(text: "First") {
                FirstView()
            }
            ButtonView(text: "Second") {
                SecondView()
            }
        }
    }
}

它会像一个魅力一样工作:)

 类似资料:
  • 问题内容: 目前,我正在使用此Javadoc语法引用其他类中的方法: 根据我从文档中了解到的,这是执行此操作的正确方法。但是现在到了有趣的部分,还是令人沮丧。当我生成此javadoc时,首先出现以下错误: 生成的HTML代码是: 当然,我没有任何联系。谁能告诉我发生了什么,以及有关如何解决此问题的任何提示? 根据ASCII表,用于wold的字符123和64分别表示{和@,因此,根据文档,当此语法正

  • 我的线性布局中有一个回收视图。 问题是,当我膨胀这个回收者视图时,完整的活动没有滚动(只有回收者视图的一部分滚动)。此外,我有指定高度的回收视图,否则我无法看到它。 所以我的两个问题是: 如何动态地给这个回收站视图高度(不工作) 当内容更多时,如何滚动整个活动(而不仅仅是回收站视图部分)。 另外,我是Android新手,虽然我之前已经实现了recyclerView,但在这些情况下只有一个元素(父L

  • 我正在尝试模拟react bootstrap

  • 如何拥有绑定类型的可选参数

  • 需要一些非常具体的包装器和例程。