TechnologiesSwiftUI

UIViewControllerRepresentableContext struct

iOSmacOStvOSwatchOSvisionOS✓ renders

Contextual information about the state of the system that you use to create

How it works

UIViewControllerRepresentableContext carries the SwiftUI state that a UIViewControllerRepresentable needs each time SwiftUI creates or updates the UIKit controller it wraps. SwiftUI constructs the context for you and passes it into makeUIViewController(context:) and updateUIViewController(_:context:), so your bridging code never instantiates it directly. Reach for the context whenever your wrapped controller must reflect the surrounding SwiftUI environment, react to an animated transaction, or call back into a coordinator — it is the single channel through which SwiftUI hands that information across the UIKit boundary.

  1. Receive the context through the Context typealias

    UIViewControllerRepresentable exposes a nested Context typealias bound to UIViewControllerRepresentableContext, and SwiftUI supplies an instance to each lifecycle method. In LabelController, both makeUIViewController(context:) and updateUIViewController(_:context:) declare a context: Context parameter that you read from rather than create.

  2. Read SwiftUI state with context.environment

    The environment property is an EnvironmentValues snapshot, giving your UIKit controller the same fonts, colors, layout direction, and other values that SwiftUI views see. makeUIViewController reads context.environment.accentColor and feeds it through UIColor(context.environment.accentColor) so the hosted UILabel adopts the SwiftUI accent color.

  3. Coordinate animations with context.transaction

    The transaction property describes the current update — including any active animation — so changes pushed into UIKit can match SwiftUI's timing instead of snapping. The update path in updateUIViewController(_:context:) can consult context.transaction to decide whether a refresh, such as re-assigning label.text, should be animated.

  4. Bridge back to SwiftUI through context.coordinator

    When the representable defines a Coordinator, the context vends it through context.coordinator, giving the UIKit controller a stable object to forward delegate and target-action callbacks into SwiftUI. LabelController keeps no coordinator, but the same context that delivers environment and transaction is where you would reach it.

Try it — Change the .accentColor(.blue) modifier on LabelController to .accentColor(.red) and watch the hosted UILabel recolor, since its color is read from context.environment.accentColor.

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.

UIViewControllerRepresentableContext.swift
struct UIViewControllerRepresentableContextDemo: View {
    struct LabelController: UIViewControllerRepresentable {
        let text: String

        func makeUIViewController(context: Context) -> UIViewController {
            // context: UIViewControllerRepresentableContext provides
            // the coordinator, environment, and current transaction.
            let controller = UIViewController()
            let label = UILabel()
            label.text = text
            label.textColor = UIColor(context.environment.accentColor)
            label.textAlignment = .center
            controller.view = label
            return controller
        }

        func updateUIViewController(_ controller: UIViewController, context: Context) {
            // context.environment / context.transaction drive updates.
            if let label = controller.view as? UILabel {
                label.text = text
            }
        }
    }

    var body: some View {
        VStack(spacing: 12) {
            Text("UIKit via Representable")
                .font(.headline)
            LabelController(text: "Hosted UILabel")
                .accentColor(.blue)
                .frame(height: 60)
        }
        .padding()
    }
}
Live preview
UIKit via Representable
UIKit via Representable
swift → lexer → parser → sema → uiir → canvas Open in Studio ↗
What's new in SwiftUI 27 →