swift - 将带有参数的闭包传递给 SwiftUI View

标签 swift

我正在开发一个 SwiftUI 项目。我创建了一个可以向其传递函数的自定义按钮。看起来如下所示。

自定义按钮

struct CustomButton: View {
    let buttonTitle: String
    var function: () -> Void
    
    var body: some View {
        Button(action: {
            self.function()
        }, label: {
            Text(self.buttonTitle)
        }) // Button - Login
    } // View
}

在使用它的 View 中,我可以执行以下操作。

struct NewView: View {
    var body: some View {
        CustomButton(buttonTitle: "Custom Button", function: myFunc)
    }
}

func myFunc() {
    print("My Custom Button Tapped")
}

这非常有效。

我现在想做的是将参数传递给函数。我在这方面遇到了麻烦。我尝试了以下方法。

struct CustomButton: View {
    let buttonTitle: String
    var function: (String) -> Void
    
    var body: some View {
        Button(action: {
            self.function() // I DON'T KNOW WHAT DO TO HERE.
        }, label: {
            Text(self.buttonTitle)
        }) // Button - Login
    } // View
}

struct NewView: View {
    var body: some View {
        CustomButton(buttonTitle: "Custom Button", function: myFunc(text: "Hello"))
    }
}

func myFunc(text: String) {
    print(text)
}

这不起作用。当我调用 CustomButton 时,出现以下错误。

Cannot convert value of type '()' to expected argument type '() -> Void'

我也不知道要向 Button 操作中的 self.function() 调用添加什么参数。

任何帮助将不胜感激。

最佳答案

首先,最简单的答案 - 通过将 myFunc(text: "Hello") 括在 { } 中,您可以将其变成闭包。然后,它可以传递到您原始的 () -> Void 声明。

struct CustomButton: View {
    let buttonTitle: String
    let function : () -> Void
    
    var body: some View {
        Button(action: {
            self.function()
        }, label: {
            Text(self.buttonTitle)
        }) // Button - Login
    } // View
}

struct NewView: View {
    var body: some View {
        CustomButton(buttonTitle: "Custom Button", function: {
            myFunc(text: "Hello")
        })
    }
}

您还可以使用 @autoclosure 来提供类似的行为,而无需 { },但您必须声明一个自定义 init对于您的自定义按钮:

struct CustomButton: View {
    let buttonTitle: String
    let function : () -> Void
    
    init(buttonTitle: String, function: @autoclosure @escaping () -> Void) {
        self.buttonTitle = buttonTitle
        self.function = function
    }
    
    var body: some View {
        Button(action: {
            self.function()
        }, label: {
            Text(self.buttonTitle)
        }) // Button - Login
    } // View
}

struct NewView: View {
    var body: some View {
        CustomButton(buttonTitle: "Custom Button", function: myFunc(text:"Hello"))
    }
}

最后,另一种选择(我认为不太可能有用例,但以防万一)是单独传递字符串参数:

struct CustomButton: View {
    let buttonTitle: String
    let stringParameter : String
    let function : (String) -> Void
    
    var body: some View {
        Button(action: {
            self.function(stringParameter)
        }, label: {
            Text(self.buttonTitle)
        }) // Button - Login
    } // View
}

struct NewView: View {
    var body: some View {
        CustomButton(buttonTitle: "Custom Button", stringParameter: "Hello", function: myFunc)
    }
}

关于swift - 将带有参数的闭包传递给 SwiftUI View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69730888/

相关文章:

swift - 使 UIColor Codable - 符合协议(protocol) 'Encodable'

ios - UIKit 以编程方式 : Help on different approaches when writing UI Code

swift - 我如何在 Swift 中尽可能简洁地说 “if x == A or B or C”?

ios - 如何区分原型(prototype) UITableViewCells 中同一 View 的实例

ios - UILabel 的滑动动画

ios - 如何有条件地使 StackView 中的图像居中

swift - 尽管 URL 正确,AVPlayer 仍无法播放

ios - 如何解决使用未解析的标识符 'SetOptions'?

通用数组的 Swift 错误

ios - UIButton 的渐变不显示