Skip to content

Instantly share code, notes, and snippets.

@Rukh
Created November 17, 2024 13:11
Show Gist options
  • Save Rukh/d310df751a261133531f393437ae388a to your computer and use it in GitHub Desktop.
Save Rukh/d310df751a261133531f393437ae388a to your computer and use it in GitHub Desktop.
Proxying properties from button style
//
// ProxyButton.swift
// Test
//
// Created by Dmitry Gulyagin on 01/11/2024.
//
import SwiftUI
struct ProxyButtonState: Equatable {
let isPressed: Bool
let role: ButtonRole?
}
struct ProxyButton<Label>: View where Label: View {
typealias Action = @MainActor () -> Void
typealias LabelBuilder = (_ config: ProxyButtonState) -> Label
private struct Style: ButtonStyle {
let label: LabelBuilder
func makeBody(configuration: Configuration) -> some View {
label(ProxyButtonState(
isPressed: configuration.isPressed,
role: configuration.role
))
}
}
private let action: Action
private let label: LabelBuilder
init(
action: @escaping Action,
@ViewBuilder label: @escaping LabelBuilder
) {
self.action = action
self.label = label
}
var body: some View {
// Replace default label (1) to label (2) from style
Button(
action: action,
label: EmptyView.init // 1
).buttonStyle(
Style(label: label) // 2
)
}
}
#Preview {
ProxyButton(
action: { print("Tap") },
label: { state in
ZStack {
Capsule()
.fill(state.isPressed ? .green : .blue)
.frame(width: 200, height: 50)
Text(state.isPressed ? "Pressed" : "Not pressed")
.foregroundColor(.white)
.padding()
.id(state.isPressed)
.transition(
.move(edge: state.isPressed ? .top : .bottom)
.combined(with: .opacity)
)
}
.animation(.default, value: state.isPressed)
}
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment