How it works
UIViewRepresentableContext is the coordinating value that SwiftUI hands to your UIViewRepresentable during makeUIView(context:) and updateUIView(_:context:). It carries the information a wrapped UIKit view needs in order to behave like a first-class SwiftUI view: the current environment values flowing down from ancestors, the type-erased coordinator you supplied, and the active transaction describing any in-flight animation. Reach for it whenever your UIKit view must respond to SwiftUI state — reading the surrounding environment, routing delegate callbacks back into SwiftUI, or honoring an animation — rather than being configured once and left static. You never construct a UIViewRepresentableContext yourself; SwiftUI creates it and passes it in on every make and update pass.
Receive the context in makeUIView(context:) and updateUIView(_:context:)
Both required methods of UIViewRepresentable take a UIViewRepresentableContext, surfaced through the Context type alias. SwiftUI calls makeUIView once to build the underlying view and updateUIView every time dependent state changes, supplying a fresh context each time. In the example,
makeUIView(context:)returns a configuredUILabelandupdateUIView(_:context:)re-applies the latest values, so the parameter namedcontextis your single entry point to everything SwiftUI knows at that moment.Read SwiftUI state through context.environment
The environment property exposes the full EnvironmentValues resolved at your view's position in the hierarchy — colors, fonts, color scheme, layout direction, and accessibility settings. This is how a UIKit view stays in sync with SwiftUI without its own @Environment bindings. The example reads
context.environment.accentColorto tint the label, picking up the.accentColor(.purple)applied by an ancestor.React to dynamic type and accessibility from the environment
Because context.environment is recomputed on every update pass, you can branch on accessibility traits to keep the wrapped view adaptive. Here
context.environment.dynamicTypeSizeis checked against.largeto choose between a.title2and.bodypreferred font, so the hostedUILabelgrows and shrinks with the user's Dynamic Type setting just as a native Text would.Route delegate work through context.coordinator
The coordinator property returns the instance produced by your makeCoordinator() method, type-erased to Coordinator. It is the durable object that lives alongside the view, so it is where you place target-action handlers and UIKit delegates that need to push events back into SwiftUI. The example keeps a stateless
LabelRep, so it omits a coordinator, butcontext.coordinatoris the member you would reach for the moment the wrapped view needs to talk back.Honor animations via context.transaction
The transaction property describes the Transaction driving the current update, including whether changes are animated and with what curve. Inspecting it lets your UIKit view wrap its own mutations in a matching UIView animation so updates coordinate with SwiftUI's. The example updates
uiView.textdirectly, but consultingcontext.transactionis what you would add to make those mutations animate in step with surrounding SwiftUI changes.
.accentColor(.purple) to .accentColor(.orange) and watch the hosted UILabel re-tint, proving the color is read live from context.environment.accentColor rather than baked in at makeUIView time.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.
struct UIViewRepresentableContextDemo: View {
struct LabelRep: UIViewRepresentable {
let text: String
func makeUIView(context: Context) -> UILabel {
let label = UILabel()
label.textColor = UIColor(context.environment.accentColor ?? .blue)
label.textAlignment = .center
return label
}
func updateUIView(_ uiView: UILabel, context: Context) {
uiView.text = text
uiView.font = .preferredFont(forTextStyle: context.environment.dynamicTypeSize >= .large ? .title2 : .body)
}
}
var body: some View {
VStack(spacing: 12) {
Text("UIViewRepresentableContext")
.font(.headline)
LabelRep(text: "Hosted UILabel, styled via context.environment")
.frame(height: 44)
}
.accentColor(.purple)
.padding()
}
}