Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
805 views
in Technique[技术] by (71.8m points)

swift - Custom Button in SwiftUI List

SwiftUI Custom Button in List

I'm trying to create a custom button in a SwiftUI List. I want it to have a blue background with white text, and importantly, to remain blue and go to 50% opacity when pressed, not the default grey.

I tried using a custom ButtonStyle, but when I do so, the tappable area of the button is reduced to just the label itself. If I tap any other part of the cell, the colour doesn't change. If I remove the ButtonStyle, tapping anywhere on the cell works

How can I fix this so that I get my custom colours, including the colour when tapped, but the whole cell is still tappable?

import SwiftUI

struct BlueButtonStyle: ButtonStyle {

  func makeBody(configuration: Self.Configuration) -> some View {
    configuration.label
        .font(.headline)
        .foregroundColor(configuration.isPressed ? Color.white.opacity(0.5) : Color.white)
        .listRowBackground(configuration.isPressed ? Color.blue.opacity(0.5) : Color.blue)
  }
}

struct ExampleView: View {

    var body: some View {
        NavigationView {
            List {
                Section {
                    Text("Info")
                }

                Section {
                    Button(action: {print("pressed")})
                    {
                        HStack {
                            Spacer()
                            Text("Save")
                            Spacer()
                        }

                    }.buttonStyle(BlueButtonStyle())
                }
            }
            .listStyle(GroupedListStyle())
            .environment(.horizontalSizeClass, .regular)
            .navigationBarTitle(Text("Title"))
        }
    }
}

struct ExampleView_Previews: PreviewProvider {
    static var previews: some View {
        ExampleView()
    }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

In standard variant List intercepts and handles content area of tap detection, in your custom style it is defined, by default, by opaque area, which is only text in your case, so corrected style is

Tested with Xcode 11.4 / iOS 13.4

demo

struct BlueButtonStyle: ButtonStyle {

  func makeBody(configuration: Self.Configuration) -> some View {
    configuration.label
        .font(.headline)
        .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center)
        .contentShape(Rectangle())
        .foregroundColor(configuration.isPressed ? Color.white.opacity(0.5) : Color.white)
        .listRowBackground(configuration.isPressed ? Color.blue.opacity(0.5) : Color.blue)
  }
}

and usage, just

Button(action: {print("pressed")})
{
    Text("Save")
}.buttonStyle(BlueButtonStyle())

and even

Button("Save") { print("pressed") }
    .buttonStyle(BlueButtonStyle())

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...