TechnologiesSwiftUI

EquatableView struct

iOSmacOStvOSwatchOSvisionOSiOS 13.0+✓ renders

A view type that compares itself against its previous value and prevents its

How it works

EquatableView is a view that wraps another view and uses that view's Equatable conformance to decide whether it actually needs to be re-rendered. Normally SwiftUI re-evaluates a view's body whenever its enclosing state changes; by comparing the old and new values of the wrapped view, EquatableView lets SwiftUI skip that work when the inputs are equal. Reach for it as a performance optimization around a view whose body is expensive to recompute and whose identity is fully captured by its stored properties.

  1. Conform the wrapped view to Equatable

    EquatableView can only short-circuit a re-render if it can compare two instances of its content, so the wrapped view must conform to Equatable. In the example, Badge is declared struct Badge: View, Equatable, and because its only stored property is let count: Int, the compiler synthesizes an == that compares badges purely by their count.

  2. Wrap the view with the content initializer

    You create the wrapper by passing the view you want to guard into EquatableView(content:). Here EquatableView(content: Badge(count: 3)) hands a Badge instance to the wrapper, which now stands in for that badge in the view tree and takes over the decision of when to re-evaluate its body.

  3. Let equality gate the re-render

    On each update, EquatableView compares the new content value against the previous one using the synthesized ==. If they are equal it reuses the existing rendering and does not re-run the wrapped body; only an unequal value triggers a fresh evaluation of Badge.body — the Label, padding, and background that make up the badge.

  4. Prefer the equatable() modifier in practice

    EquatableView is most often applied through the equatable() modifier rather than constructed by hand: Badge(count: 3).equatable() produces the same EquatableView wrapper. Spelling it out as EquatableView(content:), as the example does, makes the wrapping explicit while behaving identically.

Try it — Change Badge(count: 3) to a value driven by @State and toggle it between two distinct numbers versus repeatedly re-applying the same number — EquatableView re-renders only when count actually changes.

Example & preview

Press Run live & edit to compile it in your browser — then edit the Swift on the left and the preview re-renders live.

EquatableView.swift
struct EquatableViewDemo: View {
    struct Badge: View, Equatable {
        let count: Int
        var body: some View {
            Label("\(count) items", systemImage: "shippingbox.fill")
                .padding(8)
                .background(.blue.opacity(0.15), in: Capsule())
        }
    }

    var body: some View {
        VStack(spacing: 12) {
            Text("EquatableView")
                .font(.headline)
            EquatableView(content: Badge(count: 3))
            Text("Re-renders only when count changes")
                .font(.caption)
                .foregroundStyle(.secondary)
        }
        .padding()
    }
}
Live preview
EquatableView Re-renders only when count changes
EquatableView Re-renders only when count changes
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →