Button SwiftUI-在视图中包装按钮,以创建自定义按钮

Button SwiftUI-在视图中包装按钮,以创建自定义按钮,button,swiftui,Button,Swiftui,我正试图创建自己版本的按钮,将其包装到视图中,从而打开添加更多功能/隐藏样式修改器的功能。我知道这不会带来好处,而且钮扣样式很强大。但是出于超级干净代码的利益,我对如何实现它很感兴趣 在它最精简的形式中,我想写一些类似的东西(基于巴顿自己的签名): 然而当我尝试使用它的时候 struct MyView : View { var body : some View { MyCustomButton(action: { doSomething() }) {

我正试图创建自己版本的按钮,将其包装到视图中,从而打开添加更多功能/隐藏样式修改器的功能。我知道这不会带来好处,而且钮扣样式很强大。但是出于超级干净代码的利益,我对如何实现它很感兴趣

在它最精简的形式中,我想写一些类似的东西(基于巴顿自己的签名):

然而当我尝试使用它的时候

struct MyView : View {
    var body : some View {
        MyCustomButton(action: { doSomething() }) {
            Text("My custom button")
        }
    }
}

…我得到以下编译错误:无法将类型“Text”的值转换为闭包结果类型“PrimitiveButtonStyleConfiguration.Label”

您不需要更改按钮,根据SwiftUI的设计意图,只需要提供自定义的按钮样式,如下面的示例所示

struct ScaleButtonStyle: ButtonStyle {
    let bgColor: Color
    func makeBody(configuration: Self.Configuration) -> some View {
        configuration.label
            .background(bgColor)
            .scaleEffect(configuration.isPressed ? 5 : 1)
    }
}

struct DemoScaleButtonStyle: View {
    var body: some View {
        Button(action: { }) {
            Text("Button")
                .foregroundColor(.white)
        }.buttonStyle(ScaleButtonStyle(bgColor: Color.red))
    }
}

我已经弄明白了这一点:

struct NewButton<Content: View> : View {
    let content : ()-> Content
    let action: () -> Void

    init(@ViewBuilder content: @escaping () -> Content, action: @escaping () -> Void) {
        self.content = content
        self.action = action
    }

    var body: some View {
        Button(action: self.action) {
            content()
        }
    }
}
struct NewButton:视图{
让内容:()->内容
让行动:()->无效
init(@ViewBuilder内容:@escaping()->content,操作:@escaping()->Void){
self.content=内容
行动
}
var body:一些观点{
按钮(操作:self.action){
内容()
}
}
}

是-我知道可以使用按钮样式。然而,我想更进一步——基于我在React中所做的一些工作,人们可以将一个视图包装到另一个视图中,并添加功能,而不仅仅是样式。我也知道有ViewModifier,但它们的语法感觉不太自然。如果我想一想一般性的问题,人们如何编写自己的“HStack”,并保持语法样式,而不是我们今天使用的trailing.modifier(HStack())。
struct NewButton<Content: View> : View {
    let content : ()-> Content
    let action: () -> Void

    init(@ViewBuilder content: @escaping () -> Content, action: @escaping () -> Void) {
        self.content = content
        self.action = action
    }

    var body: some View {
        Button(action: self.action) {
            content()
        }
    }
}