Skip to content

Commit 193c63f

Browse files
authored
feat(iOS, SplitView): Add an option for changing number of columns dynamically (#3339)
## Description Previously, the constructor of UISplitViewController relied on a predefined number of columns, and we enforced this constraint using an assert to prevent unexpected runtime behavior when the number of children changed dynamically. Inspired by the `expo-router` approach, this PR removes the static assert and introduces a more dynamic pattern: the `SplitViewHost` now actively monitors the number of child columns. If the number of children changes, the entire `UISplitViewController` is remounted to reflect the updated configuration. Fixes software-mansion/react-native-screens-labs#499 . ## Changes - Added counters to monitor the number of columns and inspectors ## Screenshots / GIFs Here you can add screenshots / GIFs documenting your change. You can add before / after section if you're changing some behavior. ### Before https://github.com/user-attachments/assets/8474db46-9c87-4523-a6fc-effae0ad8555 ### After https://github.com/user-attachments/assets/7a5522c2-c9c8-4afe-8b1f-a3144f97b140 ## Test code and steps to reproduce Run any example with SplitView and add/remove columns or inspector. ## Checklist - [x] Included code example that can be used to test this change - [x] Ensured that CI passes
1 parent 51b1836 commit 193c63f

File tree

1 file changed

+20
-1
lines changed

1 file changed

+20
-1
lines changed

src/components/gamma/split-view/SplitViewHost.tsx

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import type {
66
SplitViewHostProps,
77
SplitViewSplitBehavior,
88
} from './SplitViewHost.types';
9+
import SplitViewScreen from './SplitViewScreen';
910

1011
// According to the UIKit documentation: https://developer.apple.com/documentation/uikit/uisplitviewcontroller/displaymode-swift.enum
1112
// Only specific pairs for displayMode - splitBehavior are valid and others may lead to unexpected results.
@@ -59,8 +60,26 @@ function SplitViewHost(props: SplitViewHostProps) {
5960
}
6061
}, [preferredDisplayMode, preferredSplitBehavior]);
6162

63+
const children = React.Children.toArray(props.children);
64+
65+
const columns = children.filter(
66+
// @ts-ignore - type is valid attribute for child
67+
child => child.type === SplitViewScreen.Column,
68+
);
69+
70+
const inspectors = children.filter(
71+
// @ts-ignore - type is valid attribute for child
72+
child => child.type === SplitViewScreen.Inspector,
73+
);
74+
6275
return (
63-
<SplitViewHostNativeComponent {...props} style={styles.container}>
76+
<SplitViewHostNativeComponent
77+
// UISplitViewController requires the number of columns to be specified at initialization and it cannot be changed dynamically later.
78+
// By using a specific key in this form, we can detect changes in the number of React children.
79+
// This enables us to fully recreate the SplitView when necessary, ensuring the correct column configuration is always applied.
80+
key={`columns-${columns.length}-inspectors-${inspectors.length}`}
81+
{...props}
82+
style={styles.container}>
6483
{props.children}
6584
</SplitViewHostNativeComponent>
6685
);

0 commit comments

Comments
 (0)