Description
When using FlashList v2 with dynamic-sized list items (form fields with varying heights), the bottom section of the list is not rendered on iOS when scrolling to the end.
The same code works perfectly on Android, where all items are rendered correctly.
This issue is not related to the keyboard or inputs expanding — it occurs even with static items that have variable heights.
Current behavior
On iOS:
- The last few items are not displayed.
- The list footer and padding are visible, meaning the list's end is calculated, but the items just above the footer are not rendered
- Increasing
drawDistance values fixes the rendering issue but causes performance problems and inconsistent behavior on other forms with different item counts
On Android:
- All items render as expected with no issues
Steps to reproduce:
- Create a FlashList with 40–50+ form fields of varying heights (text inputs, dropdowns, date pickers, signature fields, etc.)
- Scroll to the bottom of the list on iOS
- Observe that some bottom items are missing or not rendered until you slightly scroll back up
- Run the same code on Android — the full list is visible and renders correctly
Expected behavior
All list items should render correctly on iOS, just as they do on Android, when scrolling to the bottom. The list should not require platform-specific drawDistance calculations to render all items properly.
Reproduction
⚠️ Note: This issue occurs in a complex production app with form fields and dynamic content. A minimal reproduction would require setting up:
- Multiple form field types with varying heights
- 40-50+ items in the list
- ScrollToIndex functionality
- Dynamic content updates
Code from production app:
<FlashList
ref={flatListRef}
data={fields}
extraData={[fields, formData?.defined, formHidden]}
renderItem={renderItem}
keyExtractor={(item, index) => {
const baseKey = item.id || item.dbId || `item_${index}`;
const typeKey = item.type || 'unknown';
return `${baseKey}_${typeKey}_${index}`;
}}
getItemType={item => item.type || 'default'}
// === ISSUE: drawDistance needs platform-specific adjustment ===
// This workaround doesn't fully work - causes issues on some forms
drawDistance={
Platform.OS === 'ios'
? Math.round(
screenContext.windowHeight *
Math.max(1.321, visibleFields?.length / 42),
)
: Math.round(screenContext.windowHeight) // Works fine on Android
}
maxItemsInRecyclePool={100}
maintainVisibleContentPosition={{
minIndexForVisible: 0,
autoscrollToTopThreshold: 1,
}}
overrideProps={{
getItemCount: () => visibleFields?.length || 0,
getItem: (data, index) => data?.[index],
}}
removeClippedSubviews={false}
scrollEventThrottle={32}
decelerationRate="fast"
nestedScrollEnabled={true}
keyboardDismissMode="interactive"
keyboardShouldPersistTaps="always"
contentContainerStyle={{
paddingBottom: screenContext.windowHeight * 0.05,
}}
viewabilityConfig={{
minimumViewTime: 100,
itemVisiblePercentThreshold: 10,
}}
/>
Expo Snack or minimal reproduction link:
Currently not available - this occurs in a production React Native app with complex form logic. Will work on creating a minimal reproduction if needed.
Platform
Environment
React Native info output:
System:
OS: macOS 26.0.1
CPU: (10) arm64 Apple M4
Memory: 143.42 MB / 16.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 23.11.0
path: /opt/homebrew/bin/node
Yarn:
version: 1.22.22
path: /opt/homebrew/bin/yarn
npm:
version: 10.9.2
path: /opt/homebrew/bin/npm
Watchman:
version: 2025.04.14.00
path: /opt/homebrew/bin/watchman
Managers:
CocoaPods:
version: 1.16.2
path: /Users/saif/.rbenv/shims/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 25.0
- iOS 26.0
- macOS 26.0
- tvOS 26.0
- visionOS 26.0
- watchOS 26.0
Android SDK:
API Levels:
- "35"
Build Tools:
- 35.0.0
Android NDK: Not Found
IDEs:
Android Studio: 2025.1 AI-251.26094.121.2513.14007798
Xcode:
version: 26.0.1/17A400
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.15
path: /usr/bin/javac
Ruby:
version: 3.2.2
path: /Users/saif/.rbenv/shims/ruby
npmPackages:
"@react-native-community/cli":
installed: 20.0.0
wanted: 20.0.0
react:
installed: 19.1.0
wanted: 19.1.0
react-native:
installed: 0.81.4
wanted: 0.81.4
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: true
newArchEnabled: true
iOS:
hermesEnabled: true
newArchEnabled: true
FlashList version: 2.1.0
Additional context
Attempted Workaround (Not Fully Working)
We've tried implementing a platform-specific dynamic drawDistance calculation for iOS:
drawDistance={
Platform.OS === 'ios'
? Math.round(windowHeight * Math.max(1.321, visibleFields.length / 42))
: Math.round(windowHeight)
}
Why this workaround fails:
- ❌ It requires magic numbers (1.321, 42) that don't scale properly
- ❌ Different forms with different item counts need different multipliers
- ❌ When the multiplier is too high, it causes rendering issues and performance problems on some forms
- ❌ When the multiplier is too low, bottom items don't render on other forms
- ❌ It's unreliable and inconsistent across different forms in the same app
- ✅ Android works perfectly with just
Math.round(windowHeight) without any adjustments
The core issue: There's no reliable formula to calculate the correct drawDistance for iOS across different forms with varying item counts and heights. The value that fixes one form breaks another.
Analysis
- This happens only on iOS (tested on iOS 17.x, both simulator and real devices)
- Keyboard, SafeAreaView, and TextInput resizing are not related to the issue
- Appears to be a viewport measurement or virtualization issue specific to iOS layout calculations
- Setting a higher
drawDistance (e.g., windowHeight * 1.5 or using a formula based on item count) fixes the rendering but introduces other problems
Key Questions
- Why does iOS require a larger
drawDistance than Android for the same content?
- Is there a way to make FlashList automatically calculate the correct
drawDistance based on the actual content height?
- Can the viewport prediction algorithm be improved to handle variable-height items more accurately on iOS?
Root cause hypothesis: FlashList v2's viewport prediction on iOS might slightly under-measure the scrollable area when dealing with variable-height items, causing the last few items to fall outside the visible rendering window until re-scrolled. The Android implementation appears to handle this correctly.
Checklist
Description
When using FlashList v2 with dynamic-sized list items (form fields with varying heights), the bottom section of the list is not rendered on iOS when scrolling to the end.
The same code works perfectly on Android, where all items are rendered correctly.
This issue is not related to the keyboard or inputs expanding — it occurs even with static items that have variable heights.
Current behavior
On iOS:
drawDistancevalues fixes the rendering issue but causes performance problems and inconsistent behavior on other forms with different item countsOn Android:
Steps to reproduce:
Expected behavior
All list items should render correctly on iOS, just as they do on Android, when scrolling to the bottom. The list should not require platform-specific
drawDistancecalculations to render all items properly.Reproduction
Code from production app:
Expo Snack or minimal reproduction link:
Currently not available - this occurs in a production React Native app with complex form logic. Will work on creating a minimal reproduction if needed.
Platform
Environment
React Native info output:
FlashList version: 2.1.0
Additional context
Attempted Workaround (Not Fully Working)
We've tried implementing a platform-specific dynamic
drawDistancecalculation for iOS:Why this workaround fails:
Math.round(windowHeight)without any adjustmentsThe core issue: There's no reliable formula to calculate the correct
drawDistancefor iOS across different forms with varying item counts and heights. The value that fixes one form breaks another.Analysis
drawDistance(e.g.,windowHeight * 1.5or using a formula based on item count) fixes the rendering but introduces other problemsKey Questions
drawDistancethan Android for the same content?drawDistancebased on the actual content height?Root cause hypothesis: FlashList v2's viewport prediction on iOS might slightly under-measure the scrollable area when dealing with variable-height items, causing the last few items to fall outside the visible rendering window until re-scrolled. The Android implementation appears to handle this correctly.
Checklist