Skip to content

Controls ​

Zoom and fit-to-view control buttons for the SwiftFlow canvas.

Basic Usage ​

swift
SwiftFlow(nodes: nodes, edges: edges, ...) { node in
    MyNodeView(node: node)
} overlay: {
    Controls()
}

Customization ​

swift
// Zoom only (no fit button)
Controls(showZoom: true, showFitView: false)

// Fit only (no zoom buttons)
Controls(showZoom: false, showFitView: true)

// Different position
Controls(position: .bottomRight)

// With interactive toggle
Controls(showInteractive: true)

Adding Custom Buttons ​

Extend Controls with your own buttons:

swift
Controls(position: .bottomLeft) {
    Divider()
    ControlButton(action: {
        // Custom action
    }) {
        Image(systemName: "arrow.clockwise")
            .font(.system(size: 14, weight: .medium))
    }
}

Use ControlButton for consistent styling with the built-in zoom buttons.

Parameters ​

PropertyTypeDefaultDescription
showZoomBooltrueShow zoom in/out buttons and zoom percentage
showFitViewBooltrueShow fit-to-view button
showInteractiveBoolfalseShow interactive mode toggle
positionPanelPosition.bottomLeftPanel position on canvas
children() -> ChildrenEmptyView()ViewBuilder for additional custom buttons

PanelPosition Values ​

| .topLeft | .topCenter | .topRight | | .centerLeft | .center | .centerRight | | .bottomLeft | .bottomCenter | .bottomRight |

How It Works ​

Controls reads viewport state from the SwiftFlowState environment object and applies changes through it. The zoom buttons call zoomIn(), zoomOut(), and zoomTo(1.0) on the state, while the fit button fits the view using the canvas fitViewOptions. Each zoom step is a factor of 1.2. Button accessibility labels come from accessibilityConfig (zoomInAriaLabel, zoomOutAriaLabel, fitViewAriaLabel, interactiveAriaLabel, controlsAriaLabel).

The zoom percentage display shows the current zoom level as an integer percentage (e.g., "100%" at default zoom).

Styling ​

Controls are rendered with a .ultraThinMaterial background, 8pt corner radius, and a subtle gray border. The panel is fixedSize() so it doesn't expand to fill the canvas.

SwiftUI-native node graph editor.