# iOS Accessibility Issue: StoryBlock in Column Layout

### Problem

When `StoryBlock` is placed in a `Column` with other widgets (like `Text`), iOS VoiceOver accessibility fails:

* VoiceOver cannot interact with `StoryBlock` properly
* Tapping `StoryBlock` reads the wrong content (e.g., the `Text` label)

{% hint style="info" %}
In this problem scenario, when iOS VoiceOver is enabled, although elements within the StoryBlock—such as the Play/Pause button—are not selectable or readable through direct tap, they remain fully accessible and can be navigated and read using horizontal swipe gestures, thereby maintaining full compliance with WCAG Accessibility standards.
{% endhint %}

### Root Cause

**This is a Flutter framework limitation on iOS** when combining `Column` layouts with Platform Views, not a `StoryBlock` bug. Flutter's `Column` widget has semantic tree issues with Platform Views specifically on iOS:

1. **Semantic Node Presence**: When a widget before `StoryBlock` creates a semantic node (like `Text`), it interferes with `StoryBlock`'s accessibility on iOS
2. **Semantic Merging**: `Column` merges child semantics, causing the `Text` label to dominate and obscure `StoryBlock`'s interactive elements

**Note**: The exact mechanism is complex and may involve coordinate transformation issues in Flutter's iOS accessibility bridge. The empirical finding is clear: **any semantic node before a Platform View in a `Column` causes the problem on iOS**. This affects `UiKitView` on iOS. **Android (`PlatformViewLink`) is not affected**.

### Solution

Use `ListView` instead of `Column`:

```dart
// ❌ DON'T: Using Column
Column(
  children: [
    Text("Story Block Title"),
    StoryBlock(...),
  ],
)

// ✅ DO: Using ListView
ListView(
  shrinkWrap: true,                              // Fits content like Column
  physics: const NeverScrollableScrollPhysics(), // Disables scrolling
  children: [
    Text("Story Block Title"),
    StoryBlock(...),
  ],
)
```

#### Why ListView Works

`ListView` provides semantic isolation through Flutter's Sliver protocol:

* Each child has an independent coordinate system (no cumulative offsets)
* No automatic semantic merging
* Clear accessibility boundaries

#### Parameters Explained

* `shrinkWrap: true` - Makes ListView fit its content height (behaves like Column)
* `physics: NeverScrollableScrollPhysics()` - Disables scrolling to avoid gesture conflicts

### Alternative (Not Recommended)

If `ListView` is not feasible, use `ExcludeSemantics` to hide other widgets from accessibility:

```dart
Column(
  children: [
    ExcludeSemantics(
      child: Text("Story Block Title"),  // ⚠️ Not accessible to VoiceOver
    ),
    StoryBlock(...),
  ],
)
```

**Trade-off**: The wrapped widget becomes invisible to screen readers.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.firework.com/firework-for-developers/flutter-sdk/integration-guide-v2/ios-accessibility-issue-storyblock-in-column-layout.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
