From 5d08aab526b2702b46ff75ea7e943a33aa6df288 Mon Sep 17 00:00:00 2001 From: Ahmed Ibrahim Date: Sun, 26 Jan 2020 19:44:28 -0800 Subject: [PATCH] Disable `usesFontLeading` for NSLayoutManager on iOS to fix baseline alignment issue on some fonts (#27195) Summary: Fixes https://github.com/facebook/react-native/issues/27137 This PR fixes an issue on iOS where RCTTextView height is not calculated as it should for some fonts where font `leading` attributed is not equal to zero, which results in wrong baseline alignment behaviour. The fix for this is by setting `usesFontLeading` property of `NSLayoutManager` to `NO`, which results is a layout behavior that is similar to `UILabel` Probably the documentation for `usesFontLeading` describes why UILabel has a different (correct) layout behavior in that case > // By default, a layout manager will use leading as specified by the font. However, this is not appropriate for most UI text, for which a fixed leading is usually specified by UI layout guidelines. These methods allow the use of the font's leading to be turned off. ## Changelog [iOS] [Fixed] - Fix RCTTextView layout issue that happens on some font with `leading` attribute not equal to zero, which causes wrong base-alignment layout Pull Request resolved: https://github.com/facebook/react-native/pull/27195 Test Plan: Below are the test results before and after the change, and comparing that to native UILabel behavior. The test is done with using system font and custom font (`GothamNarrow-Medium`) and font size 50 [GothamNarrow-Medium.otf.zip](https://github.com/facebook/react-native/files/3832143/GothamNarrow-Medium.otf.zip) ```js const App: () => React$Node = () => { return ( {'Settings'} ); }; ``` ------- ### Before the fix Screenshot 2019-11-11 at 16 53 26 ----- ### After the fix Screenshot 2019-11-11 at 16 55 11 ----- ### Using `UILabel` Screenshot 2019-11-11 at 16 59 28 Differential Revision: D19576556 Pulled By: shergin fbshipit-source-id: 4eaafdab963c3f53c461884c581e205e6426718a --- Libraries/Text/Text/RCTTextShadowView.m | 1 + .../textlayoutmanager/platform/ios/RCTTextLayoutManager.mm | 1 + 2 files changed, 2 insertions(+) diff --git a/Libraries/Text/Text/RCTTextShadowView.m b/Libraries/Text/Text/RCTTextShadowView.m index a9fa9136292aed..2d4955f357586a 100644 --- a/Libraries/Text/Text/RCTTextShadowView.m +++ b/Libraries/Text/Text/RCTTextShadowView.m @@ -233,6 +233,7 @@ - (NSTextStorage *)textStorageAndLayoutManagerThatFitsSize:(CGSize)size textContainer.maximumNumberOfLines = _maximumNumberOfLines; NSLayoutManager *layoutManager = [NSLayoutManager new]; + layoutManager.usesFontLeading = NO; [layoutManager addTextContainer:textContainer]; NSTextStorage *textStorage = diff --git a/ReactCommon/fabric/textlayoutmanager/platform/ios/RCTTextLayoutManager.mm b/ReactCommon/fabric/textlayoutmanager/platform/ios/RCTTextLayoutManager.mm index 2474170f262aa9..2c3a3e93411106 100644 --- a/ReactCommon/fabric/textlayoutmanager/platform/ios/RCTTextLayoutManager.mm +++ b/ReactCommon/fabric/textlayoutmanager/platform/ios/RCTTextLayoutManager.mm @@ -97,6 +97,7 @@ - (void)drawAttributedString:(AttributedString)attributedString textContainer.maximumNumberOfLines = paragraphAttributes.maximumNumberOfLines; NSLayoutManager *layoutManager = [NSLayoutManager new]; + layoutManager.usesFontLeading = NO; [layoutManager addTextContainer:textContainer]; NSTextStorage *textStorage =