Skip to content

Instantly share code, notes, and snippets.

@ryanlintott
Last active February 25, 2024 01:15
Show Gist options
  • Save ryanlintott/e825c04ce542c236279d62f97082d292 to your computer and use it in GitHub Desktop.
Save ryanlintott/e825c04ce542c236279d62f97082d292 to your computer and use it in GitHub Desktop.
A SwiftUI ButtonStyle that looks like an iOS keyboard key.
//
// KeyboardButtonStyle.swift
// Wordhord
//
// Created by Ryan Lintott on 2024-02-06.
//
import ShapeUp
import SwiftUI
struct KeyboardButtonStyle: ButtonStyle {
let cornerRadius: CGFloat
let padding: CGFloat
init(cornerRadius: CGFloat = 8, padding: CGFloat = 8) {
self.cornerRadius = cornerRadius
self.padding = padding
}
func makeBody(configuration: Configuration) -> some View {
configuration.label
.accessibilityAddTraits(.isKeyboardKey)
.padding(padding)
.foregroundColor(configuration.isPressed ? .clear : .oeLabel)
.colorScheme(.dark)
.background {
RoundedRectangle(cornerRadius: cornerRadius)
.fill(.tint)
}
.background {
if configuration.isPressed {
CornerCustom { rect in
rect.points(relativeLocations: [
(-0.3, -1.6),
(1.3, -1.6),
(1.3, -0.3),
(1, 0),
(1, 1),
(0, 1),
(0, 0),
(-0.3, -0.3)
])
.corners(.rounded(radius: .absolute(cornerRadius)))
}
.fill(.tint)
}
}
.overlay {
GeometryReader { proxy in
Color.clear.overlay {
if configuration.isPressed {
configuration.label
.padding(padding)
.font(.largeTitle)
.foregroundColor(.oeLabel)
.colorScheme(.dark)
.fixedSize()
.offset(y: -proxy.size.height * 1.35)
}
}
}
}
/// only iOS 17
.transaction(value: configuration.isPressed) { transaction in
if configuration.isPressed {
transaction.animation = .linear.speed(100)
} else {
transaction.animation = .linear.speed(100).delay(0.2)
}
}
/// uncomment for iOS 16 and lower. Doesn't have the nice delay on disappear.
// .animation(nil, value: configuration.isPressed)
}
}
extension ButtonStyle where Self == KeyboardButtonStyle {
static var keyboardButton: Self {
KeyboardButtonStyle()
}
}
#Preview {
HStack {
Button("þ") { }
Button("ð") { }
Button("æ") { }
}
.buttonStyle(.keyboardButton)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment