Search Docs
Loading...
Skip to content

Undo and History

Manage undo and redo operations in CE.SDK programmatically, subscribe to history changes, and use multiple independent history stacks for isolated editing contexts.

5 mins
estimated time
GitHub

CE.SDK automatically tracks editing operations, enabling users to undo and redo changes. The engine creates undo steps for most operations automatically. You can also create multiple independent history stacks to isolate editing contexts — for example, separate histories for a main canvas and an overlay editor.

Setup#

We start by creating a scene and page. The engine automatically creates a history stack when it initializes.

let scene = try engine.scene.create()
let page = try engine.block.create(.page)
try engine.block.setWidth(page, value: 800)
try engine.block.setHeight(page, value: 600)
try engine.block.appendChild(to: scene, child: page)

Subscribing to History Changes#

Use engine.editor.onHistoryUpdated to receive notifications when the history state changes. The stream fires after any undo, redo, or new operation, making it straightforward to keep custom UI elements in sync.

let historyTask = Task {
for await _ in engine.editor.onHistoryUpdated {
let canUndo = try engine.editor.canUndo()
let canRedo = try engine.editor.canRedo()
print("History updated — canUndo: \(canUndo), canRedo: \(canRedo)")
}
}

Cancel the Task when you no longer need notifications, such as when dismissing a view.

Automatic Undo Step Creation#

Most editing operations automatically create undo steps. Adding a block to the scene records this operation in the history stack.

let block = try engine.block.create(.graphic)
try engine.block.setShape(block, shape: engine.block.createShape(.rect))
try engine.block.setWidth(block, value: 100)
try engine.block.setHeight(block, value: 100)
try engine.block.setFill(block, fill: engine.block.createFill(.color))
try engine.block.appendChild(to: page, child: block)

After creating the block, canUndo() returns true.

Performing Undo and Redo#

Use engine.editor.undo() and engine.editor.redo() to revert or restore changes. Always check availability with canUndo() and canRedo() first.

if try engine.editor.canUndo() {
try engine.editor.undo()
}

After undoing, canRedo() returns true. Call redo() to restore the change.

if try engine.editor.canRedo() {
try engine.editor.redo()
}

Managing Undo Steps Manually#

Most operations are tracked automatically. For custom operations that the engine doesn’t track, use addUndoStep() to create a checkpoint manually.

try engine.block.setWidth(block, value: 200)
try engine.editor.addUndoStep()

Use removeUndoStep() to discard the most recent undo step without affecting the redo stack.

if try engine.editor.canUndo() {
try engine.editor.removeUndoStep()
}

Working with Multiple History Stacks#

CE.SDK supports multiple independent history stacks. This is useful when different parts of your app need separate undo/redo histories. Only the active history responds to undo/redo operations.

let primaryHistory = engine.editor.getActiveHistory()
let secondaryHistory = engine.editor.createHistory()
engine.editor.setActiveHistory(secondaryHistory)
// Operations here only affect secondaryHistory
try engine.block.setWidth(block, value: 300)
engine.editor.setActiveHistory(primaryHistory)
engine.editor.destroyHistory(secondaryHistory)
  • Create a stack with createHistory() and activate it with setActiveHistory()
  • Operations while a stack is active only affect that stack
  • Always call destroyHistory() when a stack is no longer needed to free resources

API Reference#

MethodPurpose
engine.editor.createHistory()Create a new undo/redo history stack
engine.editor.destroyHistory(_:)Destroy a history stack and free resources
engine.editor.setActiveHistory(_:)Set a history stack as the active one
engine.editor.getActiveHistory()Get the currently active history stack
engine.editor.addUndoStep()Manually add a checkpoint to the undo stack
engine.editor.removeUndoStep()Remove the most recent undo step
engine.editor.undo()Revert to the previous history state
engine.editor.redo()Restore the next history state
engine.editor.canUndo()Check if an undo operation is available
engine.editor.canRedo()Check if a redo operation is available
engine.editor.onHistoryUpdatedSubscribe to history change notifications

Next Steps#

  • Events — subscribe to block creation, update, and deletion events
  • Editor State — track selection and edit mode changes
  • Scenes — create and manage design scenes