web-dev-qa-db-ja.com

SwiftUIリストのカスタムボタン

リスト内のSwiftUIカスタムボタン

SwiftUIリストにカスタムボタンを作成しようとしています。私はそれが白いテキストで青い背景になり、そして重要なことに、デフォルトの灰色ではなく、青色のままで、押されたときに50%の不透明度にしたいです。

カスタムButtonStyleを使用してみましたが、使用すると、ボタンのタップ可能な領域がラベル自体に縮小されます。セルの他の部分をタップしても、色が変わりません。 ButtonStyleを削除すると、セルのどこかをタップしても機能します

これを修正して、タップしたときの色を含むカスタムカラーを取得できますが、セル全体はタップ可能です。

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

標準のバリアントリストでは、タップ検出のコンテンツ領域をインターセプトして処理します。カスタムスタイルでは、デフォルトで不透明領域によって定義されます。これは、ケース内のテキストのみなので、修正されたスタイルは

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

と使用法、

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

そして

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