【问题标题】:SwiftUI - wrapping Button in a view, to create a custom buttonSwiftUI - 在视图中包装 Button,以创建自定义按钮
【发布时间】:2020-04-28 12:47:46
【问题描述】:

我正在尝试创建自己的 Button 版本,方法是将其包装在视图中,从而打开添加更多功能/隐藏样式修饰符的能力。我知道这不会带来好处,而且 ButtonStyles 很强大。但是为了超级干净的代码,我对它是如何实现的很感兴趣。

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

struct MyCustomButton: View {
    let action : () -> Void
    let contents : () -> PrimitiveButtonStyleConfiguration.Label

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

然而当我尝试使用它时......

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

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

【问题讨论】:

    标签: button swiftui


    【解决方案1】:

    想通了:

    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()
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      您无需更改Button,根据 SwiftUI 设计意图,只需提供自定义ButtonStyle,如下例所示。

      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))
          }
      }
      
      

      【讨论】:

      • 是的 - 我知道可以使用 ButtonStyles。然而,我想更进一步——基于我在 React 中所做的一些工作,可以将视图包装在另一个视图中,并添加功能,而不仅仅是样式。我也知道有 ViewModifiers,但它们的语法感觉不那么自然。如果我要考虑通用问题,如何编写自己的“HStack”,并保持语法风格,而不是我们今天拥有的尾随 .modifier(HStack())。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-01-24
      • 1970-01-01
      • 1970-01-01
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多