Skip to content

Instantly share code, notes, and snippets.

@Czajnikowski
Last active May 13, 2022 09:55
Show Gist options
  • Save Czajnikowski/1a35463217777af93e7d7959a44d1514 to your computer and use it in GitHub Desktop.
Save Czajnikowski/1a35463217777af93e7d7959a44d1514 to your computer and use it in GitHub Desktop.
Standalone button handling and affording undo/redo actions (implemented without overgeneralizing the implementation above my own needs). An answer to https://stackoverflow.com/questions/60647857/undomanagers-canundo-property-not-updating-in-swiftui/67354446#67354446
import SwiftUI
import Combine
struct UndoManagerActionButton: View {
enum Action {
case
undo,
redo
}
private let action: Action
private let willChangePublisher: AnyPublisher<Void, Never>
@Environment(\.undoManager) private var undoManger: UndoManager!
@State private var canPerformAction = false
init<WillChangePublisher>(
_ action: Action,
willChangePublisher: WillChangePublisher
) where WillChangePublisher: Publisher, WillChangePublisher.Failure == Never {
self.action = action
self.willChangePublisher = willChangePublisher
.map { _ in () }
.eraseToAnyPublisher()
}
var body: some View {
Group {
if canPerformAction {
Button(
action: action == .undo ? undoManger.undo : undoManger.redo,
label: { Text(action == .undo ? "Undo" : "Redo") }
)
}
else {
EmptyView()
}
}
.onReceive(
willChangePublisher,
perform: { _ in
canPerformAction = action == .undo ? undoManger.canUndo : undoManger.canRedo
}
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment