Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(iOS): back button does not respect I18nManager & improve RTL hand…
…ling in header (software-mansion#2185) ## Description This PR intents to fix back button direction in RTL mode forced by I18nManager for testing purposes on iOS. When the application's language is changed using the `CFBundleDevelopmentRegion` the system is well aware of that, passes the information to React Native and Yoga. The result is a fully LTR / RTL compliant application. However, when the `RTL` mode is set using the React Native's `I18nManager.forceRTL()` method (for testing purposes I believe) The change is applied to react views only and the system itself does not change it's direction. In such case the only way for the native elements, such as `navigationBar` to adapt to the direction set by `I18nManager` is by manually applying the `semanticContentAttribute` based on `direction` prop passed by `react-navigation`. > [!note] In case there is another native `navigationBar` element apart from the one coming from `react-native-screens`, this change may override it's direction. Tested successfully on iOS 17.5 and 16.4 Fixes software-mansion#1884 . ## Changes - removed faulty workaround - set correct semanticContentAttribute for navigationBar and it's contents - refactored how the searchbar direction is set ## Screenshots / GIFs ### Before ![image](https://github.com/software-mansion/react-native-screens/assets/91994767/1c67071d-92e4-4966-9ad8-362c54c4435b) ### After ![image](https://github.com/software-mansion/react-native-screens/assets/91994767/5cf40cf1-b762-4720-af33-0f939adac7c5) ## Test code and steps to reproduce - play around with LTR and RTL mode in the example app ## Checklist - [ ] Included code example that can be used to test this change - [ ] Updated TS types - [ ] Updated documentation: <!-- For adding new props to native-stack --> - [ ] https://github.com/software-mansion/react-native-screens/blob/main/guides/GUIDE_FOR_LIBRARY_AUTHORS.md - [ ] https://github.com/software-mansion/react-native-screens/blob/main/native-stack/README.md - [ ] https://github.com/software-mansion/react-native-screens/blob/main/src/types.tsx - [ ] https://github.com/software-mansion/react-native-screens/blob/main/src/native-stack/types.tsx - [ ] Ensured that CI passes ## Short story on how RTL management works in RN apps on iOS by @kkafar > [!note] > Basically we have two RTL management systems: native one & ReactNative's I18nManager. > > Native one works most likely by applying semantic content attribute to all the views / classes and impacting layout constraints, thus whole native application is laid out properly. > We can impact RTL on natively managed views by: > * setting semantic content attributes for particular view > * [setting semantic content attributes for particular class through appearance proxy](https://developer.apple.com/documentation/uikit/uiappearance?language=objc) > * [setting semantic content attributes for particular class contained in instances of another class](https://developer.apple.com/documentation/uikit/uiappearance/1615006-appearancewhencontainedin?language=objc) > > Topic's to research: > * how parent's semantic content attribute (set directly on given view) does affect subviews > * exact semantics of using appearance proxy object, their priority and resolve order. > > > React Native has notion of internationalisation manager (I18n) which works as follows: > > * The RTL is allowed by default. > * If RTL is not forced from JS, and allowed, then system language writing direction is resolved based on system calls and such obtained interface direction is passed down to Yoga *impacting all views that are laid out by Yoga*, but not purely native ones such as our header. Thus leading to conformity between system options and RN app options. > * If RTL is forced from JS and allowed, them Yoga managed views are laid out in RTL mode, while system managed ones respect the system settings. > * ForceRTL / AllowRTL flags are stored in `NSUserDefaults` application persistent storage, thus living through application restarts. These flags are RN specific, and system has no knowledge of them. > > React Navigation takes the value from RN I18n system and passes it down to our screen / stack / header components. --------- Co-authored-by: Kacper Kafara <kacperkafara@gmail.com> Co-authored-by: Kacper Kafara <kacper.kafara@swmansion.com>
- Loading branch information