Button - tkgstrator/Salmonia3 GitHub Wiki

モダンな丸ボタン

import SwiftUI

struct ContentView: View {
    var body: some View {
        LazyVGrid(columns: Array(repeating: .init(.flexible(minimum: 60, maximum: 80)), count: 3), alignment: .center, spacing: 10, pinnedViews: []) {
            ForEach(Range(0...11)) { number in
                Button(action: {}, label: { Text("\(number)").frame(width: 60, height: 60, alignment: .center) })
                    .overlay(
                        Circle()
                            .stroke(Color.blue, lineWidth: 1)
                    )
            }
        }
    }
}

LazyVGridと組み合わせると簡単に電話や電卓で使えそうなボタンが作成できる

Overlayの部分も押せる判定がでるのは良いことなのだが、押したときに色の変化が起こらないという問題がある

というわけで以下のようなカスタムButtonStyleを作成する

import SwiftUI

struct ContentView: View {
    var body: some View {
        LazyVGrid(columns: Array(repeating: .init(.flexible(minimum: 60, maximum: 80)), count: 3), alignment: .center, spacing: 10, pinnedViews: []) {
            ForEach(Range(0...11)) { number in
                Button(action: {}, label: {
                    Text("\(number)")
                        .frame(width: 60, height: 60, alignment: .center)
                })
                .buttonStyle(ModernButtonStyle())
            }
        }
    }
}

struct CircleButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .foregroundColor(configuration.isPressed ? Color.white : Color.blue)
            .overlay(Circle().stroke(Color.blue, lineWidth: 1))
            .background(Circle().foregroundColor(configuration.isPressed ? Color.blue : Color.clear))
    }
}

色の指定はUIColorをColorに変換すると手っ取り早い

ここのページでRGBカラーコードからUIColorに変換してくれるのでそれを利用した

Color(UIColor(red: 0.458, green: 0.603, blue:0.894, alpha: 1.000)

alphaの値は省略すれば自動的に1.0が適用されるので、不透明にしたい場合は省略してしまっても問題ない

個人的にこの色合いはとても好きなのでいろいろなところで利用していきたい

電卓っぽいボタン

import SwiftUI

struct ContentView: View {
    var body: some View {
        LazyVGrid(columns: Array(repeating: .init(.flexible(minimum: 60, maximum: 80), spacing: 0), count: 3), alignment: .center, spacing: 10, pinnedViews: []) {
            ForEach(Range(0...11)) { number in
                Button(action: {}, label: {
                    switch number {
                    case 0...8:
                        Text("\(1 + number)")
                            .frame(width: 60, height: 60, alignment: .center)
                    case 10:
                        Text("0")
                            .frame(width: 60, height: 60, alignment: .center)
                    case 9:
                        Image(systemName: "minus")
                            .frame(width: 60, height: 60, alignment: .center)
                    case 11:
                        Image(systemName: "chevron.backward")
                            .frame(width: 60, height: 60, alignment: .center)
                    default:
                        EmptyView()
                    }
                })
                .buttonStyle(CircleButtonStyle())
            }
        }
    }