Skip to content

Instantly share code, notes, and snippets.

@chriseidhof
Created June 6, 2025 05:53
Show Gist options
  • Save chriseidhof/f18a77442bb7b46a74b6cd693daf5f61 to your computer and use it in GitHub Desktop.
Save chriseidhof/f18a77442bb7b46a74b6cd693daf5f61 to your computer and use it in GitHub Desktop.
import SwiftUI
struct ControllerActionPrefereneceKey: PreferenceKey {
static let defaultValue: [ControllerAction] = []
static func reduce(value: inout [ControllerAction], nextValue: () -> [ControllerAction]) {
value.append(contentsOf: nextValue())
}
}
struct ControllerActionModifier: ViewModifier {
@Namespace var id
var title: String
var perform: () -> ()
var enabled: Bool
func body(content: Content) -> some View {
content
.transformPreference(ControllerActionPrefereneceKey.self, { arr in
arr.append(.init(id: id, enabled: enabled, title: title, perform: perform))
})
}
}
extension View {
func action(_ name: String, enabled: Bool = true, perform: @escaping () -> ()) -> some View {
modifier(ControllerActionModifier(title: name, perform: perform, enabled: enabled))
}
}
struct ControllerAction: Identifiable, Equatable {
var id: Namespace.ID
var title: String
var enabled: Bool
var perform: () -> ()
init(id: Namespace.ID, enabled: Bool, title: String, perform: @escaping () -> Void) {
self.id = id
self.title = title
self.perform = perform
self.enabled = enabled
}
static func == (lhs: ControllerAction, rhs: ControllerAction) -> Bool {
// The `perform` closure is never compared and should always be the same closure
lhs.id == rhs.id && lhs.title == rhs.title && lhs.enabled == rhs.enabled
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment