Created
October 31, 2022 16:11
-
-
Save allenhumphreys/89b920790c97246fb7f96c82bdca8de8 to your computer and use it in GitHub Desktop.
SwiftUI Custom Button Implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ContentView.swift | |
// GoGoButtons | |
// | |
// Created by Allen Humphreys on 10/31/22. | |
// | |
import SwiftUI | |
extension Color { | |
init(hex: String) { | |
let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted) | |
var int: UInt64 = 0 | |
Scanner(string: hex).scanHexInt64(&int) | |
let a, r, g, b: UInt64 | |
switch hex.count { | |
case 3: // RGB (12-bit) | |
(a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17) | |
case 6: // RGB (24-bit) | |
(a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF) | |
case 8: // ARGB (32-bit) | |
(a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF) | |
default: | |
(a, r, g, b) = (1, 1, 1, 0) | |
} | |
self.init( | |
.sRGB, | |
red: Double(r) / 255, | |
green: Double(g) / 255, | |
blue: Double(b) / 255, | |
opacity: Double(a) / 255 | |
) | |
} | |
} | |
extension Color { | |
static var CustomButtonText: Color { | |
// #2F7185 | |
Color(hex: "#2F7185") | |
} | |
static var CustomButtonBackground: Color { | |
// #2F7185 | |
Color(hex: "#f5f5f5") | |
} | |
} | |
class CustomColor: UIColor { | |
override func resolvedColor(with traitCollection: UITraitCollection) -> UIColor { | |
if traitCollection.activeAppearance == .active { | |
return self | |
} else { | |
return .red | |
} | |
} | |
} | |
struct CustomButton: View { | |
let configuration: ButtonStyle.Configuration | |
@Environment(\.isEnabled) private var isEnabled: Bool | |
@Environment(\.scenePhase) var scenePhase | |
@Environment(\.isPresented) var isPresented: Bool | |
@Environment(\.isFocused) var isFocused: Bool | |
var body: some View { | |
configuration.label | |
.padding() | |
.background(Color.CustomButtonBackground) | |
.foregroundColor(.CustomButtonText) | |
.background(in: Capsule()) | |
.animation(.easeOut(duration: 0.2), value: configuration.isPressed) | |
.onChange(of: isEnabled, perform: { newValue in | |
print("isEnabled: \(newValue)") | |
}) | |
.onChange(of: scenePhase) { newValue in | |
//nothing | |
print("Phase: \(newValue)") | |
} | |
.onChange(of: isPresented) { newValue in | |
print("isPresented: \(newValue)") | |
} | |
.onChange(of: isFocused) { newValue in | |
print("isFocused: \(newValue)") | |
} | |
} | |
} | |
struct CustomButtonConfiguration: ButtonStyle { | |
func makeBody(configuration: Configuration) -> some View { | |
CustomButton(configuration: configuration) | |
} | |
} | |
struct ContentView: View { | |
@State | |
var alert: String = "" | |
@State | |
private var alertShowing = false | |
var body: some View { | |
VStack(alignment: .leading) { | |
Button("Bordered") { | |
alert = "Bordered" | |
alertShowing = true | |
} | |
.buttonStyle(.bordered) | |
.padding([.top, .bottom]) | |
Button("Bordered Prominent") { | |
alert = "Bordered Prominent" | |
alertShowing = true | |
} | |
.buttonStyle(.borderedProminent) | |
.padding([.top, .bottom]) | |
Button("Borderless") { | |
alert = "Borderless" | |
alertShowing = true | |
} | |
.buttonStyle(.borderless) | |
.padding([.top, .bottom]) | |
Button("Plain") { | |
alert = "Plain" | |
alertShowing = true | |
} | |
.buttonStyle(.plain) | |
.padding([.top, .bottom]) | |
Button("Custom Button") { | |
alert = "Custom" | |
alertShowing = true | |
} | |
.padding([.top, .bottom]) | |
.buttonStyle(CustomButtonConfiguration()) | |
} | |
.alert(isPresented: $alertShowing, content: { | |
Alert( | |
title: Text(alert), | |
dismissButton: .default(Text("OK")) | |
) | |
}) | |
} | |
} | |
struct ContentView_Previews: PreviewProvider { | |
static var previews: some View { | |
ContentView() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment