首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SwiftUI传递ViewModifier作为参数

SwiftUI传递ViewModifier作为参数
EN

Stack Overflow用户
提问于 2021-01-16 18:02:31
回答 3查看 2.9K关注 0票数 4

我正在创建一个自定义TextField视图,该视图由多个装饰视图组成。我希望能够设置内部TextField的视图修饰符,如键盘,大写等,只适用于该子视图。

与其为每个属性创建属性,我认为最好的方法是传入一个可选的ViewModifier参数并使用它,如下所示:

代码语言:javascript
复制
struct MySuperTextField: View {
    var vm: ViewModifier?

    var body: some View {
         TextField(...)
           .modifier( vm ?? EmptyModifier() )
         // ... more views here
    }
}

由于associatedType in ViewModifier,这是不起作用的。唉,也没有像AnyViewModifier这样的东西(我也想不出如何使它起作用)。

有人能做这样的事吗?我在网上找不到任何东西。

一个例子就是

代码语言:javascript
复制
struct LastNameModifier: ViewModifier {
   func body(content: Content) -> some View {
       content
          .autocapitalization(.words)
          .textContentType(.familyName)
          .backgroundColor(.green)
          // ... anything else specific to names
   }
}

struct EmailModifier: ViewModifier {
   func body(content: Content) -> some View {
       content
          .keyboardType(.emailAddress)
          .textContentType(.emailAddress)
          .backgroundColor(.yellow)
          // ... anything else specific to emails
   }
}

然后像这样在我的MySuperTextField中使用它们:

代码语言:javascript
复制
VStack {
    MySuperTextField("Last Name", $lastName, vm: LastNameModifier())

    MySuperTextField("Email", $email, vm: EmailModifier())
}
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-01-17 18:01:37

如果我正确理解,您可以让MySuperTextField接受一个通用参数:

代码语言:javascript
复制
struct MySuperTextField<V>: View where V: ViewModifier {
    private let placeholder: String
    @Binding private var text: String
    private let vm: V
    
    init(_ placeholder: String, text: Binding<String>, vm: V) {
        self.placeholder = placeholder
        self._text = text
        self.vm = vm
    }

    var body: some View {
        TextField(placeholder, text: $text)
            .modifier(vm)
    }
}

然后,可以传递一些ViewModifier作为参数:

代码语言:javascript
复制
struct ContentView: View {
    @State private var text: String = "Test"

    var body: some View {
        MySuperTextField("Last Name", text: $text, vm: LastNameModifier())
    }
}

如果您需要在创建vm时跳过MySuperTextField参数

代码语言:javascript
复制
MySuperTextField("Last Name", text: $text)

您可以创建一个扩展:

代码语言:javascript
复制
extension MySuperTextField where V == EmptyModifier {
    init(_ placeholder: String, text: Binding<String>) {
        self.placeholder = placeholder
        self._text = text
        self.vm = EmptyModifier()
    }
}
票数 5
EN

Stack Overflow用户

发布于 2021-01-17 18:04:37

由于ViewModifier有一个关联类型,您不能将其用作实例变量,但我建议您使用另一种方法:

MySuperTextField不必维护ViewModifier类型的实例。

代码语言:javascript
复制
struct MySuperTextField: View {
    @State var textValue = ""

    var body: some View {
        TextField("", text: $textValue)
    }
}

对于每个符合ViewModifier协议的结构,您可以创建一个扩展:

代码语言:javascript
复制
extension MySuperTextField {
    func lastNameModifier() -> some View {
        modifier(LastNameModifier())
    }

    func emailModifier() -> some View {
        modifier(EmailModifier())
    }
}

你可以这样用它:

代码语言:javascript
复制
struct ContentView : View {
    var body: some View {
        VStack {
            MySuperTextField(textValue: "Last Name")
                .lastNameModifier()
            MySuperTextField(textValue: "Email")
                .emailModifier()
        }
    }
}
票数 0
EN

Stack Overflow用户

发布于 2021-01-16 18:30:14

将ViewModifier设置为一个结构,然后在视图上调用它。您只需特定于类型,例如我使用的这个buttonStyle修饰符:

代码语言:javascript
复制
struct PurchaseButtonStyle: ButtonStyle {
    let geometry: GeometryProxy
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .frame(minWidth: 0, idealWidth: 300, maxWidth: .infinity)
            .padding(.all, geometry.size.height / 30)
            .foregroundColor(.black)
            .background(.orange)
            .cornerRadius(30)

    }
}

其用途是:

代码语言:javascript
复制
Button(...)
    .buttonStyle(PurchaseButtonStyle(geometry: Geometry))

您只需编写它就可以成为特定的修饰符。我之所以使用这个,是因为它在我正在开发的一个应用程序中非常方便。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65752883

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档