How to set custom highlighted state of SwiftUI But

2020-02-05 07:27发布

问题:

I have a Button. I want to set custom background color for highlighted state. How can I do it in SwiftUI?

Button(action: signIn) {
    Text("Sign In")
}
.padding(.all)
.background(Color.red)
.cornerRadius(16)
.foregroundColor(.white)
.font(Font.body.bold())

回答1:

Updated for SwiftUI beta 5

SwiftUI does actually expose an API for this: ButtonStyle.

struct MyButtonStyle: ButtonStyle {

  func makeBody(configuration: Self.Configuration) -> some View {
    configuration.label
      .padding()
      .foregroundColor(.white)
      .background(configuration.isPressed ? Color.red : Color.blue)
      .cornerRadius(8.0)
  }

}


// To use it
Button(action: {}) {
  Text("Hello World")
}
.buttonStyle(MyButtonStyle())



回答2:

As far as I can tell, theres no officially supported way to do this as of yet. Here is a little workaround that you can use. This produces the same behavior as in UIKit where tapping a button and dragging your finger off of it will keep the button highlighted.

struct HoverButton<Label>: View where Label: View {

    private let action: () -> ()

    private let label: () -> Label

    init(action: @escaping () -> (), label: @escaping () -> Label) {
        self.action = action
        self.label = label
    }

    @State private var pressed: Bool = false

    var body: some View {
        Button(action: action) {
            label()
                .foregroundColor(pressed ? .red : .blue)
                .gesture(DragGesture(minimumDistance: 0.0)
                    .onChanged { _ in self.pressed = true }
                    .onEnded { _ in self.pressed = false })
        }    
    }
}


回答3:

I was looking for a similar functionality and I did it in the following way.

I created a special View struct returning a Button in the style I need, in this struct I added a State property selected. I have a variable named 'table' which is an Int since my buttons a round buttons with numbers on it

struct TableButton: View {
    @State private var selected = false

    var table: Int

    var body: some View {
        Button("\(table)") {
            self.selected.toggle()
        }
        .frame(width: 50, height: 50)
        .background(selected ? Color.blue : Color.red)
        .foregroundColor(.white)
        .clipShape(Circle())
    }
}

Then I use in my content View the code

HStack(spacing: 10) {
  ForEach((1...6), id: \.self) { table in
    TableButton(table: table)
  }
}

This creates an horizontal stack with 6 buttons which color blue when selected and red when deselected.

I am not a experienced developer but just tried all possible ways until I found that this is working for me, hopefully it is useful for others as well.



标签: swiftui