skip to content

In Flutter on iOS, how does a UiKitView platform view compose with Flutter content, and which composition limits should you expect?

level: seniorimportance: nice to knowfreq 16%

answer

  1. iOS uses only hybrid composition
  2. UIView appended to the view hierarchy
  3. ShaderMask and ColorFiltered unsupported
  4. BackdropFilter works with limits
  5. gestureBlockingPolicy for misbehaving recognizers

basics

~20 s

On iOS, Flutter uses only hybrid composition: the native UIView is added to the view hierarchy and Flutter content is layered around it. ShaderMask and ColorFiltered do not apply to the native view, and BackdropFilter works only with limitations.

solid answer

~40 s

Unlike Android's several modes, iOS platform views always use **hybrid composition**: the `UIView` created by a `FlutterPlatformViewFactory` is appended to the native view hierarchy, and Flutter content that overlaps it from above goes into extra overlay layers. Transforms, clips and opacity from Dart still apply, but the docs list composition limits: `ShaderMask` and `ColorFiltered` are not supported over the native view, and `BackdropFilter` works only with restrictions. Touches also need care: when Flutter wins a gesture, it must block the `UIView`'s own `UIGestureRecognizer`s, and `UiKitView.gestureBlockingPolicy` (default `fallbackToPluginDefault`) offers `eager`, `waitUntilTouchesEnded` and `doNotBlockGesture` for native views whose recognizers get stuck. For heavy Dart animations over a platform view, the docs suggest showing a snapshot texture of the native view while animating.

go deeper

for a junior

Remember that iOS platform views always use hybrid composition, adding the UIView to the native view hierarchy.

for a middle

Explain the factory and view protocols on the Swift side, and list the effects that do not apply to native iOS views.

for a senior

Plan designs and animations around iOS composition limits and diagnose native gesture problems with gestureBlockingPolicy only when needed.

for a principal

Align designers and platform teams on which visual effects are feasible over native content, so iOS and Android ship the same experience.

## One mode on iOS On Android, Flutter offers texture layer, hybrid composition, virtual display and experimental HCPP. On iOS there is only one: **hybrid composition**. The docs put it plainly — the native `UIView` is appended to the view hierarchy. What that means in practice: - The native view is a real `UIView` among Flutter's own layers, so it renders with full native fidelity. - Flutter content that overlaps the platform view from above is drawn into extra overlay layers on top of it. Every overlap adds composition work. - There is no texture copy of the native view in normal rendering, so there is no "switch to texture mode" to try. ## Creating one On the Dart side: ```dart UiKitView( viewType: 'com.example.property/map', creationParams: const <String, Object?>{'lat': 52.37, 'lng': 4.89}, creationParamsCodec: const StandardMessageCodec(), ) ``` On the Swift side, a class conforming to `FlutterPlatformViewFactory` creates a `FlutterPlatformView` whose `view()` returns the `UIView`; the factory is registered with the plugin registrar under the same `viewType`. SwiftUI content can be hosted by wrapping it in a `UIHostingController` and returning its `view`. ## Composition limits | Flutter effect over or on the native view | Status on iOS | |---|---| | Transforms, clips, opacity | Applied | | `ShaderMask` | Not supported | | `ColorFiltered` | Not supported | | `BackdropFilter` | Supported with limitations | If a design asks for a gradient fade (`ShaderMask`) over a map or a colour filter on a web view, plan an alternative on iOS — for example a Flutter-drawn overlay gradient placed above the view instead of a mask applied to it. ## Gestures on iOS The general forwarding model is the same as on Android: `gestureRecognizers` decides which gestures the native view may win. The extra iOS detail is **blocking** the `UIView`'s own `UIGestureRecognizer`s when Flutter wins. `UiKitView` exposes `gestureBlockingPolicy`, an enum `UiKitViewGestureBlockingPolicy`: 1. `eager` — block native recognizers as soon as Flutter decides they should be blocked; only `touchesBegan` is guaranteed to reach them. 2. `waitUntilTouchesEnded` — native recognizers see the whole touch sequence but never recognise; may let through touches that should have been blocked. 3. `doNotBlockGesture` — block based on hit testing only, without the gesture arena; a workaround for recognizers stuck in stale state, at the risk of recognising gestures that should have been blocked. 4. `fallbackToPluginDefault` (the default) — use the policy the plugin set when registering the view factory. Most apps never touch this; it exists for native views whose recognizers misbehave under aggressive blocking. ## Performance mitigation The docs' suggested technique for complex cases applies here too: if a Dart animation runs slowly while a platform view is on screen, take a snapshot of the native view and show it as a texture during the animation, then swap the live view back. ## Common misunderstandings - iOS platform views are not rendered into textures by default. - A `ShaderMask` that works over Flutter widgets will not mask the native view. - Changing Android's composition flags has no effect on iOS.

  • A designer wants a gradient fade over an embedded iOS map using ShaderMask. What do you propose?
    `ShaderMask` is not supported over iOS platform views, so draw a Flutter gradient container stacked above the map instead of masking it. It gives a similar look and is ordinary Flutter content composited over the view.
  • When would you change UiKitView.gestureBlockingPolicy from its default?
    Only when a specific native view's `UIGestureRecognizer`s get stuck or misfire under Flutter's blocking. Policies like `waitUntilTouchesEnded` or `doNotBlockGesture` work around such bugs but can let through touches that should have been blocked, so test carefully.

saying these in an interview costs you the question

  • iOS platform views default to texture layer mode like Android.
  • ShaderMask and ColorFiltered apply to native iOS views like any widget.
  • UiKitView has no way to adjust native gesture blocking.
  • Android's displayWithHybridComposition flag also changes iOS behaviour.